# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

# /*---------------------------------------------------------------------------8
# |                                                                            |
# |             SAP: Register BOM                                              |
# |         SAP PAS: deploy PAS Parameter file install template                |
# |         SAP PAS: Install                                                   |
# |                                                                            |
# +------------------------------------4--------------------------------------*/

---

- name:                                "PAS Install: Set the SCS Server name list"
  ansible.builtin.set_fact:
    scs_server_temp:                   "{{ scs_server_temp | default([]) + [item] }}"
  with_items:
    - "{{ query('inventory_hostnames', '{{ sap_sid | upper }}_SCS') }}"
    - "{{ query('inventory_hostnames', '{{ sap_sid | upper }}_DB') }}"

- name:                                "PAS Install: -  Set the DB Server name list"
  ansible.builtin.set_fact:
    db_server_temp:                    "{{ db_server_temp | default([]) + [item] }}"
  with_items:
    - "{{ query('inventory_hostnames', '{{ sap_sid | upper }}_DB') }}"

- name:                                "Backward Compatibility - Check required Database HA variables"
  ansible.builtin.set_fact:
    database_high_availability:        "{{ db_high_availability | default(false) }}"
  when:
    - db_high_availability is defined
    - database_high_availability is not defined

- name:                                "PAS Install: Calculate virtual host name when running scale out"
  ansible.builtin.set_fact:
    db_virtualhost_temp:  >-
                                       {%- set _host_name = hostvars[db_server_temp | first]['virtual_host'] -%}
                                       {%- if database_scale_out and not database_high_availability -%}
                                       {%-  set _host_name = sap_sid | lower ~ db_sid | lower ~ 'db' ~ db_instance_number ~ 'so' -%}
                                       {%- endif -%}
                                       {{- _host_name -}}

- name:                                "PAS Install: Set BOM facts"
  ansible.builtin.set_fact:
    sap_inifile:                       "{{ bom_base_name }}-pas-{{ sid_to_be_deployed.sid | lower }}-{{ ansible_hostname }}.params"
    sap_inifile_template:              "pas-inifile-param.j2"
    dir_params:                        "{{ tmp_directory }}/.{{ sid_to_be_deployed.sid | lower }}-params"
    db_lb_virtual_host_HANA:           "{% if database_high_availability %}{{ sid_to_be_deployed.sid | lower }}{{ db_sid | lower }}db{{ db_instance_number }}cl.{{ sap_fqdn }}{% else %}{{ db_virtualhost_temp | default(hostvars[db_server_temp | first]['virtual_host'], true) }}{% endif %}"
    db_lb_virtual_host_AnyDB:          "{% if database_high_availability %}{{ sid_to_be_deployed.sid | lower }}{{ db_sid | lower }}db{{ db_instance_number }}cl.{{ sap_fqdn }}{% else %}{{ db_server_temp }}{% endif %}"

- name:                                "PAS Install: Set BOM facts db host"
  ansible.builtin.set_fact:
    db_lb_virtual_host:                "{% if platform == 'HANA' %}{{ custom_db_virtual_hostname | default(db_lb_virtual_host_HANA, true) }}{% else %}{{ custom_db_virtual_hostname | default(db_lb_virtual_host_AnyDB, true) }}{% endif %}"

- name:                                "PAS Install: -  Create directories"
  ansible.builtin.file:
    path:                              "{{ item.path }}"
    state:                             directory
    mode:                              '{{ item.mode }}'
  loop:
    - { mode: '0755', path: '{{ dir_params }}' }
    - { mode: '0755', path: '{{ tmp_directory }}/{{ sid_to_be_deployed.sid | upper }}' }
    - { mode: '0755', path: '/etc/sap_deployment_automation/{{ sap_sid | upper }}' }

- name:                                "PAS Install: reset"
  ansible.builtin.file:
    path:                              "/etc/sap_deployment_automation/{{ sid_to_be_deployed.sid | upper }}/sap_deployment_pas.txt"
    state:                             absent
  when:                                reinstall

- name:                                "PAS Install: check if {{ sid_to_be_deployed.sid | upper }} is installed"
  ansible.builtin.stat:
    path:                              "/etc/sap_deployment_automation/{{ sid_to_be_deployed.sid | upper }}/sap_deployment_pas.txt"
  register:                            pas_installed

# Returns bom object
- name:                                "PAS Install: Register BoM"
  ansible.builtin.include_role:
    name:                              roles-sap/3.3.1-bom-utility
    tasks_from:                        bom-register
  vars:
    bom_name:                          "{{ bom_base_name }}"
    task_prefix:                       "PAS Install: "
    sa_enabled:                        true

# - name:                                "PAS Install: Default instance type"
#   ansible.builtin.set_fact:
#     instance_type:                     "ASCS"
#     public:                            true
#   when:                                bom.InstanceType is not defined

# - name:                                "PAS Install: register instance type if JAVA"
#   ansible.builtin.set_fact:
#     instance_type:                     "JAVA"
#     public:                            true
#   when:
#     - bom.InstanceType is defined
#     - bom.InstanceType | upper == 'JAVA'

- name:                                "PAS Install: register variables"
  ansible.builtin.set_fact:
    pas_bom_instance_type:             "{% if bom.InstanceType is defined %}{{ bom.InstanceType }}{% else %}ABAP{% endif %}"
    public:                            true

- name:                                "PAS Install: Check if the DB load balancer port is available and listening"
  ansible.builtin.wait_for:
    host:                              "{{ db_lb_virtual_host }}"
    port:                              "625{{ db_instance_number }}"
    state:                             started
    timeout:                           30
    msg:                               'INSTALL:0026:PAS Install failed, database is unreachable.'
  register:                            db_port_open
  failed_when:                         false
  when:
    - database_high_availability
    - platform == "HANA"

- name:                                "PAS Install: DEBUG - DB Loadbalancer check"
  ansible.builtin.debug:
    msg:                               "{{ db_port_open.msg }}"
    verbosity:                         2
  when:
    - database_high_availability
    - platform == "HANA"
    - db_port_open.msg is defined

- name:                                "ErrorHandling"
  ansible.builtin.fail:
    msg:                               "INSTALL:0026:PAS Install failed, database is unreachable."
  when:
    - database_high_availability
    - platform == "HANA"
    - db_port_open.msg is defined

- name:                               "PAS Install: Set Schema Name"
  when:
    - platform == "HANA"
  ansible.builtin.include_role:
    name:                             "roles-db/4.0.4-hdb-schema"
    public:                           true

- name:                                "PAS Install"
  block:

    # *====================================4=======================================8
    # |  SAP PAS: Install                                                          |
    # | 2230669 - System Provisioning Using a Parameter Input File                 |
    # |                                                                            |
    # *====================================4=======================================8

    - name:                            "PAS Install: Set the SCS Server name"
      ansible.builtin.set_fact:
        scs_server:                    "{% if scs_high_availability %}{{ sid_to_be_deployed.sid | lower }}scs{{ scs_instance_number }}cl1{% else %}{{ hostvars[scs_server_temp | first]['virtual_host'] }}{% endif %}"
        db_virtual_hostname:           "{{ hostvars[db_server_temp | first]['virtual_host'] }}"
        file_path:                     "{% if scs_high_availability %}INSTALL/HA/ABAP/APP1{% else %}INSTALL/DISTRIBUTED/ABAP/APP1{% endif %}"
        DB:                            "{% if MULTI_SIDS is defined %}{{ sid_to_be_deployed.sid | upper }}/HDB{{ db_instance_number }}{% else %}{{ db_sid | upper }}/HDB{{ db_instance_number }}{% endif %}"
        pas_virtual_hostname:          "{{ custom_pas_virtual_hostname | default(virtual_host, true) }}"

    - name:                            "PAS Install: check media exists"
      ansible.builtin.stat:
        path:                          "{{ target_media_location }}/SWPM/sapinst"
      register:                        sapinst_found

    - name:                            "ErrorHandling"
      ansible.builtin.fail:
        msg:                           "INSTALL:0006:Unable to find sapinst, please check that the installation media is mounted"
      when: not sapinst_found.stat.exists

    - name:                            "PAS Install: Template processing - Create ini file {{ sap_inifile }} from {{ sap_inifile_template }}"
      ansible.builtin.template:
        src:                           "{{ sap_inifile_template }}"
        dest:                          "{{ dir_params }}/{{ sap_inifile }}"
        mode:                          0644
        force:                         true
      vars:
        sap_ciInstanceNumber:          "{{ instance_number }}"
        sap_ciDialogWPNumber:          12
        sap_ciBtcWPNumber:             8
        sap_installSAPHostAgent:       "false"
        sap_profile_dir:               /sapmnt/{{ sid_to_be_deployed.sid | upper }}/profile
        sap_scs_hostname:              "{{ custom_scs_virtual_hostname | default(scs_server, true) }}"
        sap_db_hostname:               "{{ custom_db_virtual_hostname | default(db_lb_virtual_host, true) }}"
        sap_ciVirtualHostname:         "{{ pas_virtual_hostname | default(virtual_host, true) }}"
        param_directory:               "{{ dir_params }}"
        sap_sid:                       "{{ sid_to_be_deployed.sid }}"
        scs_instance_number:           "{{ sid_to_be_deployed.ascs_inst_no }}"
        sidadm_uid:                    "{{ sid_to_be_deployed.sidadm_uid }}"
        virt_do_not_resolve_hostname:  "{{ custom_db_virtual_hostname | default(db_lb_virtual_host, true) }}"
        db_schema:                     "{% if platform == 'HANA' %}{{ schema_name }}{% endif %}"

    - name:                            "PAS Install: register variables"
      ansible.builtin.set_fact:
        pas_bom_id:                    "{{ bom.product_ids.pas }}"

    - name:                            "PAS Install: install variables"
      ansible.builtin.debug:
        msg:
          - "INSTALLED:  {{ pas_installed.stat.exists }}"
          - "INIFILE:    {{ sap_inifile }}"
          - "PRODUCT ID: {{ pas_bom_id }}"
          - "INSTANCE:   {{ instance_number }}"
          - "DBHOST:     {{ custom_db_virtual_hostname | default(db_virtual_hostname, true) }}"
          - "HOST:       {{ pas_virtual_hostname }}"
          - "SID:        {{ sid_to_be_deployed.sid | upper }}"

    - name:                            "PAS Install: HANA HSR - Update Profile"
      ansible.builtin.import_tasks:    ../../../roles-db/4.0.1-hdb-hsr/tasks/4.0.1.7-sap-profile-changes.yml
      vars:
        instance_type:                 "{{ pas_bom_instance_type }}"
      when:
        - database_high_availability
        - platform == "HANA"

    - name:                            "PAS Install: Create temp directory for sid"
      ansible.builtin.file:
        path:                          "{{ tmp_directory }}/{{ sid_to_be_deployed.sid | upper }}"
        state:                         directory
        mode:                          0755

    - name:                            "PAS Install: debug"
      ansible.builtin.command:         "cat {{ dir_params }}/{{ sap_inifile }}"
      register:                        debug_inifile

    - name:                            "PAS Install: progress"
      ansible.builtin.debug:
        var:                           debug_inifile
        verbosity:                     4

    - name:                            "PAS Install: Create Symlink"
      ansible.builtin.import_tasks:    ../../../roles-sap-os/2.10-sap-notes/tasks/2.10.3119751.yaml
      when:
        - ansible_os_family == 'RedHat'

    - name:                            "PAS Install: Get hdbuserstore path"
      become:                          true
      become_user:                     "root"
      ansible.builtin.find:
        paths:                         "/usr/sap/{{ sid_to_be_deployed.sid | upper }}/SYS/exe/uc/linuxx86_64/hdbclient/,/usr/sap/{{ sid_to_be_deployed.sid }}/hdbclient"
        file_type:                     file
        patterns:                      'hdbuserstore'
        recurse:                       true
      register:                        hdbuserstore_file
      vars:
        allow_world_readable_tmpfiles: true
      when:
        - database_high_availability
        - platform == 'HANA'

    - name:                            "PAS Install: Set hdbuserstore path"
      ansible.builtin.set_fact:
        hdbuserstore_path:             "{{ hdbuserstore_file.files[0].path }}"
      when:
        - database_high_availability
        - platform == 'HANA'
        - hdbuserstore_file | length > 0

    - name:                            "PAS Install: show hdbuserstore path"
      ansible.builtin.debug:
        var:                           hdbuserstore_path
      when:
        - database_high_availability
        - platform == 'HANA'

    - name:                            "Starting PAS installation"
      block:

        - name:                            "PAS Install: Set DB Virtual Host name ({{ custom_db_virtual_hostname | default(db_lb_virtual_host, true) }})"
          become:                          true
          become_user:                     "{{ sid_to_be_deployed.sid | lower }}adm"
          ansible.builtin.shell: |
                                           {{ hdbuserstore_path }} -H {{ pas_virtual_hostname }} SET DEFAULT {{ custom_db_virtual_hostname | default(db_lb_virtual_host, true) }}:3{{ db_instance_number }}13@{{ db_sid | upper }} {{ schema_name }} {{ main_password }}
          environment:
            SAPSYSTEMNAME:                 "{{ sid_to_be_deployed.sid | upper }}"
            ssfs_connect:                  "1"
          register:                        hdbuserstore
          vars:
            allow_world_readable_tmpfiles: true
          when:
            - database_high_availability
            - platform == 'HANA'
            - hdbuserstore_path | length > 0

        - name:                            "PAS Install: Set DB Virtual Host name ({{ custom_db_virtual_hostname | default(db_lb_virtual_host, true) }})"
          become:                          true
          become_user:                     "{{ sid_to_be_deployed.sid | lower }}adm"
          ansible.builtin.shell: |
                                           {{ hdbuserstore_path }} SET DEFAULT {{ custom_db_virtual_hostname | default(db_lb_virtual_host, true) }}:3{{ db_instance_number }}13@{{ db_sid | upper }} {{ schema_name }} {{ main_password }}
          environment:
            SAPSYSTEMNAME:                 "{{ sid_to_be_deployed.sid | upper }}"
            ssfs_connect:                  "1"
          register:                        hdbuserstore
          vars:
            allow_world_readable_tmpfiles: true
          when:
            - database_high_availability
            - platform == 'HANA'
            - hdbuserstore_path | length > 0

        - name:                            "PAS Install: Ensure ownership"
          ansible.builtin.file:
            path:                          "{{ item.path }}"
            owner:                         '{{ sid_to_be_deployed.sidadm_uid }}'
            group:                         sapsys
            recurse:                       true
            state:                         directory
          loop:
            - { path: '/sapmnt/{{ sap_sid | upper }}' }
            - { path: '/usr/sap/{{ sap_sid | upper }}' }

        - name:                            "PAS Install: progress"
          ansible.builtin.debug:
            msg:                           "Starting PAS installation ({{ sid_to_be_deployed.sid | upper }})"

        - name:                            "PAS Install"
          ansible.builtin.shell: |
                                          umask {{ custom_umask | default('022') }} ;
                                          ./sapinst SAPINST_INPUT_PARAMETERS_URL={{ dir_params }}/{{ sap_inifile }} \
                                                    SAPINST_EXECUTE_PRODUCT_ID={{ pas_bom_id }}                     \
                                                    SAPINST_SKIP_DIALOGS=true                                       \
                                                    SAPINST_USE_HOSTNAME={{ pas_virtual_hostname }}                 \
                                                    SAPINST_START_GUISERVER=false
          args:
            chdir:                     "{{ target_media_location }}/SWPM"
            creates:                   "/etc/sap_deployment_automation/{{ sid_to_be_deployed.sid | upper }}/sap_deployment_pas.txt"
          environment:
            TMPDIR:                    "{{ tmp_directory }}/{{ sid_to_be_deployed.sid | upper }}"
            SAPSYSTEMNAME:             "{{ sid_to_be_deployed.sid | upper }}"
            SAPSYSTEM:                 "{{ instance_number }}"
          register:                    pas_installation
          failed_when:                 pas_installation.rc > 0

      rescue:
        - name:                        "PAS Install: Capturing the modified message for message server being offline"
          ansible.builtin.set_fact:
            modified_error_message:    "{{ pas_installation.stdout | try_get_error_code(task_tag='pasinstall', failure='messageserver_offline') }}"

        - name:                        "PAS Install: Capturing the modified message for database being offline"
          ansible.builtin.set_fact:
            modified_error_message:    "{{ modified_error_message | try_get_error_code(task_tag='pasinstall', failure='db_offline') }}"

        - name:                        "PAS Install: Show error message"
          ansible.builtin.debug:
            msg:                       "Modified error message: {{ modified_error_message }}"
          when:                        modified_error_message != pas_installation.stdout

        - name:                        "PAS Install: Fail with the modified error message "
          ansible.builtin.fail:
            msg:                       "{{ modified_error_message }}"

    - name:                            "PAS Install: Installation results"
      ansible.builtin.debug:
        var:                           pas_installation
      when:                            pas_installation.rc > 0

    - name:                            "PAS Install: Installation results"
      ansible.builtin.debug:
        msg:                           "PAS Installation succeeded"
      when:                            pas_installation.rc == 0

    - name:                            "PAS Install: Cleanup ini file {{ ansible_hostname }}"
      ansible.builtin.file:
        path:                          "{{ dir_params }}/{{ sap_inifile }}"
        state:                         absent

    - name:                            "PAS Install: Find the installationSuccesfullyFinished.dat (SAPINST)"
      ansible.builtin.find:
        paths:                         "{{ tmp_directory }}/{{ sid_to_be_deployed.sid | upper }}/sapinst_instdir/{{ bom.product_ids.pas.replace('.', '/').replace('/ABAP', '').split(':')[1] }}/{{ file_path }}"
        file_type:                     file
        patterns:                      'installationSuccesfullyFinished.dat'
        recurse:                       true
      register:                        pas_installed_according_to_sapinst

    - name:                            "PAS Install: flag"
      ansible.builtin.file:
        path:                          "/etc/sap_deployment_automation/{{ sid_to_be_deployed.sid | upper }}/sap_deployment_pas.txt"
        state:                         touch
        mode:                          0755
      when:
        - pas_installation.rc == 0
        - pas_installed_according_to_sapinst is defined
        - pas_installed_according_to_sapinst | length > 0

    - name:                            "PAS Install: Check if Standalone"
      ansible.builtin.set_fact:
        servers_temp:                  "{{ servers_temp | default([]) + [item] }}"
      with_items:
        - "{{ query('inventory_hostnames', '{{ sap_sid | upper }}_SCS') }}"
        - "{{ query('inventory_hostnames', '{{ sap_sid | upper }}_DB') }}"
        - "{{ query('inventory_hostnames', '{{ sap_sid | upper }}_PAS') }}"

    - name:                            "PAS Install: Restart SAPHostCtrl"
      become:                          true
      ansible.builtin.command:         /usr/sap/hostctrl/exe/saphostexec -restart
      register:                        saphostexec_result
      when:                            (servers_temp | length) == 1

    - name:                            "PAS Install: SAPHostCtrl output"
      ansible.builtin.debug:
        var:                           saphostexec_result
      when:                            (servers_temp | length) == 1

  when:
    - not pas_installed.stat.exists

- name:                                "PAS Install: - status"
  block:
    - name:                            "PAS Install: - status"
      ansible.builtin.debug:
        msg:                           "PAS Installation is already performed ({{ sid_to_be_deployed.sid | upper }})"

    - name:                            "PAS Install: - return value"
      ansible.builtin.set_fact:
        pas_already_installed:         true

    - name:                            "PAS Install: Calculate the virtual host name"
      ansible.builtin.set_fact:
        pas_virtual_hostname:          "{{ custom_pas_virtual_hostname | default(virtual_host, true) }}"

    - name:                            "PAS Install: Get hdbuserstore path"
      become:                          true
      become_user:                     "root"
      ansible.builtin.find:
        paths:                         "/usr/sap/{{ sid_to_be_deployed.sid | upper }}/SYS/exe/uc/linuxx86_64/hdbclient/,/usr/sap/{{ sid_to_be_deployed.sid }}/hdbclient"
        file_type:                     file
        patterns:                      'hdbuserstore'
        recurse:                       true
      register:                        hdbuserstore_file
      vars:
        allow_world_readable_tmpfiles: true
      when:
        - database_high_availability
        - platform == 'HANA'

    - name:                            "PAS Install: Set hdbuserstore path"
      ansible.builtin.set_fact:
        hdbuserstore_path:             "{{ hdbuserstore_file.files[0].path }}"
      when:
        - database_high_availability
        - platform == 'HANA'
        - hdbuserstore_file.matched > 0

    - name:                            "PAS Install: show hdbuserstore path"
      ansible.builtin.debug:
        var:                           hdbuserstore_path
      when:
        - database_high_availability
        - platform == 'HANA'

    - name:                            "PAS Install: Set DB Virtual Host name ({{ custom_db_virtual_hostname | default(db_lb_virtual_host, true) }})"
      ansible.builtin.shell: |
                                       {{ hdbuserstore_path }} -H {{ pas_virtual_hostname }} SET DEFAULT {{ custom_db_virtual_hostname | default(db_lb_virtual_host, true) }}:3{{ db_instance_number }}13@{{ db_sid | upper }} {{ schema_name }} {{ main_password }}
      environment:
        SAPSYSTEMNAME:                 "{{ sid_to_be_deployed.sid | upper }}"
        ssfs_connect:                  "1"
      register:                        hdbuserstore
      become:                          true
      become_user:                     "{{ sid_to_be_deployed.sid | lower }}adm"
      vars:
        allow_world_readable_tmpfiles: true
      when:
        - database_high_availability
        - platform == 'HANA'


  when:
    - pas_installed.stat.exists
...
# /*---------------------------------------------------------------------------8
# |                                   END                                      |
# +------------------------------------4--------------------------------------*/
