#
# Configure the Hive Metastore
#
# Note: in the case where any of the username/password/secretName
# configurations have been provided, set hive.spec.metastore.storage.create
# to false as we can make a relatively safe assumption they're providing a
# non-default database configuration.
#
# Note: for the top-level condition for this block, because json_query will
# return an empty string when an object is defined, we need to ensure that
# object is defined and non-empty before we can check if the database dictionary
# contains any keys.
- name: Configure and validate the user-provided Hive metastore configuration
  block:
  - include_tasks: update_meteringconfig_status.yml
    vars:
      current_conditions:
        type: "Running"
        status: "True"
        message: "Configuring hive metastore"
        lastTransitionTime: "{{ now(utc=False).isoformat() + 'Z' }}"

  - name: Determine the Hive underlying database
    block:
    - name: Split the hive.spec.config.db.url into an array
      set_fact:
        _url_array: "{{ _meteringconfig_hive_metastore_db_url.split(':') }}"

    - name: Verify the JDBC URL is valid before parsing
      assert:
        that:
        - '{{ _url_array[0] == "jdbc" }}'
        - '{{ _url_array[1] in ["mysql", "postgresql", "derby"] }}'
        msg: "Invalid JDBC URL {{ _meteringconfig_hive_metastore_db_url }} passed in the MeteringConfig.Spec"

    # Note: the `schematool -dbType` option expects either `mysql`,
    # `derby`, `oracle` and `postgres` as valid options. In the case
    # of the JDBC URL, only `postgresql` is valid, so we need to do
    # some re-mapping of naming if that is what has been specified
    # in the hive.spec.config.db.url field in the MeteringConfig CR.
    - name: Override the default hive metastore database type
      set_fact:
        _hive_metastore_db_type: "{{ 'postgres' if _url_array[1] == 'postgresql' else _url_array[1] }}"

  - name: Override the default hive.spec.metastore.storage.create option to false
    set_fact:
      _hive_metastore_create_default_storage: false
    when:
    - _meteringconfig_hive_metastore_db_username is defined and _meteringconfig_hive_metastore_db_username | length > 0
    - _meteringconfig_hive_metastore_db_password is defined and _meteringconfig_hive_metastore_db_password | length > 0

  - name: Manage username and password data when secretName is not empty
    block:
    - name: Validate the username and password fields are undefined when secretName is not empty
      assert:
        that:
        - _meteringconfig_hive_metastore_db_username is not defined or _meteringconfig_hive_metastore_db_username | length == 0
        - _meteringconfig_hive_metastore_db_password is not defined or _meteringconfig_hive_metastore_db_password | length == 0
        msg: "Invalid configuration for hive.spec.config.db: the username and password fields must be empty when secretName has been specified"

    - name: Query k8s for the user-provided secretName object
      k8s_info:
        api_version: v1
        kind: Secret
        name: "{{ _meteringconfig_hive_metastore_db_secretName }}"
        namespace: "{{ meta.namespace }}"
      register: hive_metastore_db_secret_buf

    - name: Create variables from the decoded username and password data
      set_fact:
        _hive_metastore_db_username: "{{ _hive_metastore_db_secret_buf_resources_first_index.data.username | b64decode }}"
        _hive_metastore_db_password: "{{ _hive_metastore_db_secret_buf_resources_first_index.data.password | b64decode }}"
        _hive_metastore_create_default_storage: false
      when:
      - hive_metastore_db_secret_buf is defined
      - _hive_metastore_db_secret_buf_resources_first_index | length > 0
    vars:
      _hive_metastore_db_secret_buf_resources_first_index: "{{ hive_metastore_db_secret_buf.resources | first }}"
    when:
    - _meteringconfig_hive_metastore_db_secretName is defined
    - _meteringconfig_hive_metastore_db_secretName | length > 0

  - include_tasks: update_meteringconfig_status.yml
    vars:
      current_conditions:
        type: "Running"
        status: "True"
        message: "Finished configuring the hive metastore"
        lastTransitionTime: "{{ now(utc=False).isoformat() + 'Z' }}"
  vars:
    _meteringconfig_hive_metastore_db_secretName: "{{ meteringconfig_spec_overrides | json_query('hive.spec.config.db.secretName') }}"
    _meteringconfig_hive_metastore_db_username: "{{ meteringconfig_spec_overrides | json_query('hive.spec.config.db.username') }}"
    _meteringconfig_hive_metastore_db_password: "{{ meteringconfig_spec_overrides | json_query('hive.spec.config.db.password') }}"
    _meteringconfig_hive_metastore_db_url: "{{ meteringconfig_spec_overrides | json_query('hive.spec.config.db.url') }}"
    _meteringconfig_hive_metastore_db_configuration: "{{ meteringconfig_spec_overrides | json_query('hive.spec.config.db') }}"
  no_log: false
  rescue:
  - include_tasks: update_meteringconfig_status.yml
    vars:
      end_play_after_updating_status: true
      current_conditions:
        type: "Invalid"
        status: "True"
        message: |
          "{{ ansible_failed_result.msg }}"
        lastTransitionTime: "{{ now(utc=False).isoformat() + 'Z' }}"
    when:
    - ansible_failed_result is defined
    - ansible_failed_result.msg | length > 0
  when:
  - _meteringconfig_hive_metastore_db_configuration is defined
  - _meteringconfig_hive_metastore_db_configuration | length > 0
  - _meteringconfig_hive_metastore_db_configuration.keys() | length > 0
