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

---
# -------------------------------------+---------------------------------------8
#
# Description:  Validation for Prerequisites
#
#   01) bom_base_name                   must be provided
#   02) deployer_kv_name or
#       kv_name                         if defined, check for s_user and s_password
#                                       else s_user and s_password must be provided
#   04) s_user                          provided or recovered from KV
#   05) s_password                      provided or recovered from KV
#   06) download_directory
#   sapbits_sas_token
#   sapbits_access_key
#   sapbits_bom_files
#   target_media_location
#   sapbits_location_base_path

# -------------------------------------+---------------------------------------8
# Step: 01
# Description:  Validation for bom_base_name
#
# Information:
#     type_debug values for testing:
#         - undefined   = AnsibleUndefined
#         - null        = NoneType
#         - text        = AnsibleUnicode
#         - boolean     = bool
#
- name:                                 "(pre_checks.yaml) - Validate required variable is present and not empty (bom_base_name)"
  ansible.builtin.assert:
    that:
      - "bom_base_name is defined"                                              # Has the variable been defined
      - "bom_base_name | type_debug != 'NoneType'"                              #  is not null
      - "bom_base_name | trim | length > 1"                                     #  and given a value
    success_msg: |-
                                        bom_base_name:                {{ bom_base_name }}
    fail_msg: |-
                                        Please ensure that the details are provided for:
                                        - bom_base_name
# Step: 01 - END
# -------------------------------------+---------------------------------------8


# -------------------------------------+---------------------------------------8
# Step: 02
# Description:  KeyVault Access
#               If neither deployer_kv_name or kv_name are defined, then skip.
#               Otherwise fetch:
#                 - s_user
#                 - s_password
#               from KeyVault when they are not already defined.
#
- name:                                 "(pre_checks.yaml) - KeyVault validation block..."
  block:

    - name:                             "(pre_checks.yaml) - {{ task_prefix }} - Informational"
      ansible.builtin.debug:
        msg: |-
                                        Entering KV Block...
        verbosity:                      1

# -------------------------------------+---------------------------------------8
# Step: 02-01
# Description:
#
    - name:                             "(pre_checks.yaml) - {{ task_prefix }} - Set deployer keyvault name"
      ansible.builtin.set_fact:
        kv_name:                        "{{ deployer_kv_name }}"
      when:                             deployer_kv_name is defined
# Step: 02-01 - END
# -------------------------------------+---------------------------------------8

# -------------------------------------+---------------------------------------8
# Step: 02-02
# Description:
#
    - name:                             "(pre_checks.yaml) - {{ task_prefix }} - Load the keyvault secrets"
      ansible.builtin.include_role:
        name:                           roles-misc/0.2-kv-secrets
        public:                         true
      vars:
        tier:                           bom
      # tags:
      #   - 0.2-kv-secrets
# Step: 02-02 - END
# -------------------------------------+---------------------------------------8

# -------------------------------------+---------------------------------------8
# Step: 02-03
# Description:
#
    - name:                             "(pre_checks.yaml) - {{ task_prefix }} - Set kv_enabled: true"
      ansible.builtin.set_fact:
        kv_enabled:                     true
      when:
        - "kv_name is defined"                                                  # Has the variable been defined
        - "kv_name | type_debug != 'NoneType'"                                  #  is not null
        - "kv_name | trim | length > 1"                                         #  and given a value
# Step: 02-03 - END
# -------------------------------------+---------------------------------------8

  vars:
    task_prefix:                        KeyVault validation block
  when:
    - ( ( kv_name          is defined     and   kv_name          | trim | length > 1 ) or
        ( deployer_kv_name is defined     and   deployer_kv_name | trim | length > 1 ) )
    # - ( ( s_user           is undefined   or    s_user           | trim | length < 1 ) or
    #     ( s_password       is undefined   or    s_password       | trim | length < 1 ) )
# Step: 02 - END
# -------------------------------------+---------------------------------------8


# -------------------------------------+---------------------------------------8
# Step: 03
# Description:  Informational check of the kv_name parameter.
#
- name:                                "(pre_checks.yaml) - Informational check of the kv_name parameter"
  ansible.builtin.assert:
    that:
      - "kv_name is defined"                                                    # Has the variable been defined
      - "kv_name | type_debug != 'NoneType'"                                    #  is not null
      - "kv_name | trim | length != 0"                                          #  and given a value
    success_msg: |-
                                        KeyVault access:  ENABLED
                                        kv_enabled:       {{ kv_enabled }}
    fail_msg: |-
                                        KeyVault access:  DISABLED
                                        kv_enabled:       {{ kv_enabled }}

                                        If this is undesired, please set:
                                        - deployer_kv_name
  failed_when:                         false
# Step: 03 - END
# -------------------------------------+---------------------------------------8


# -------------------------------------+---------------------------------------8
# Step: 04
# Description:  Validation for s_user
#
- name:                                 "(pre_checks.yaml) - Check that the S-User is present and not empty (s_user)"
  ansible.builtin.assert:
    that:
      - "s_user is defined"                                                     # Has the variable been defined
      - "s_user | type_debug != 'NoneType'"                                     #  is not null
      - "s_user | string | length != 0 "                                        #  and given a value
    success_msg: |-
                                        s_user:           {{ s_user | default('NOT DEFINED') }}
    fail_msg: |-
                                        Please ensure that the details are provided for:
                                        - s_user

                                        either as a parameter or in the deployer key vault
# Step: 04 - END
# -------------------------------------+---------------------------------------8


# -------------------------------------+---------------------------------------8
# Step: 05
# Description:  Validate that s_password parameter has been given a value
#
- name:                                 "(pre_checks.yaml) - Check that the S-User password is present and not empty (s_password)"
  ansible.builtin.assert:
    that:
      - "s_password is defined"                                                 # Has the variable been defined
      - "s_password | type_debug != 'NoneType'"                                 #  is not null
      - "s_password | string | length != 0 "                                    #  and given a value
    success_msg: |-
                                        s_password:       ***********
    fail_msg: |-
                                        Please ensure that the details are provided for:
                                        - s_password

                                        either as a parameter or in the deployer key vault
# Step: 05 - END
# -------------------------------------+---------------------------------------8


# -------------------------------------+---------------------------------------8
# Step: 06
# Description:  Validation for download_directory
#               This is the location used when downloading files from SAP. This
#               is an intermediary location to stage files before upload to SA.
#               Default: ~/tmp/downloads
#
- name:                                 "(pre_checks.yaml) - Check that the Download Directory is present and not empty (download_directory)"
  ansible.builtin.assert:
    that:
      - "download_directory is defined"                                              # Has the variable been defined
      - "download_directory | type_debug != 'NoneType'"                              #  is not null
      - "download_directory | trim | length > 1"                                     #  and given a value
    success_msg: |-
                                        download_directory:    {{ download_directory | default('NOT DEFINED') }}
    fail_msg: |-
                                        Please ensure that the details are provided for:
                                        - download_directory
# Step: 06 - END
# -------------------------------------+---------------------------------------8


# -------------------------------------+---------------------------------------8
# Step: 07
# Description:  Create BOM download directories".
#
# TODO: allow for concurrancy by using unique tmp directory dtructure.
#
- name:                                 "(pre_checks.yaml) - Prepare download directory"
  block:

# -------------------------------------+---------------------------------------8
# Step: 07-01
# Description:  Ensure download_directory exists
#
    - name:                            "{{ task_prefix }} - Create BOM download directories"
      become:                          "{{ bom_processing_become }}"
      become_user:                     root
      ansible.builtin.file:
        path:                          "{{ item }}"
        state:                         directory
        mode:                          0755
        owner:                         "{{ orchestration_ansible_user if bom_processing_become else omit }}"
      delegate_to:                     localhost
      loop:
        - "{{ download_directory }}"
        - "{{ download_directory }}/tmp"
        - "{{ download_directory }}/files"
        - "{{ download_directory }}/bom"


# Step: 07-01 - END
# -------------------------------------+---------------------------------------8

# -------------------------------------+---------------------------------------8
# Step: 07-02
# Description:  Create test file
#
    - name:                             "(pre_checks.yaml) - {{ task_prefix }} - BoM Initial file"
      ansible.builtin.copy:
        dest:                           "{{ download_directory }}/readme.md"
        content:                        "This is the container with the SAP media"
        mode:                           0644
      register:                         readme_file
      delegate_to:                      localhost
# Step: 07-02 - END
# -------------------------------------+---------------------------------------8

  vars:
    task_prefix:                        Prepare download directory block
  when:
    - download_directory
# Step: 07 - END
# -------------------------------------+---------------------------------------8


# -------------------------------------+---------------------------------------8
# Step: 08
# Description:  Storage Account Access
#               If neither deployer_kv_name or kv_name are defined, then skip.
#               Otherwise fetch:
#                 - sapbits_location_base_path
#                 - sapbits_access_key
#                 - sapbits_sas_token
#               from KeyVault when they are not already defined.
#
- name:                                 "(pre_checks.yaml) - Storage Account validation block"
  block:

    - name:                             "(pre_checks.yaml) - {{ task_prefix }} - Informational"
      ansible.builtin.debug:
        msg: |-
                                        Entering Storage Account Block...
        verbosity:                      1


# -------------------------------------+---------------------------------------8
# Step: 08-01
# Description:  Validate sapbits_bom_files
#
    - name:                             "(pre_checks.yaml) - {{ task_prefix }} - Validate required variable is present and not empty (sapbits_bom_files)"
      ansible.builtin.assert:
        that:
          - "sapbits_bom_files is defined"                                          # Has the variable been defined
          - "sapbits_bom_files | trim | length != 0"                                #   and given a value
        success_msg: |-
                                        sapbits_bom_files:            {{ sapbits_bom_files | default('NOT DEFINED') }}
        fail_msg: |-
                                        Please ensure that the details are provided for:
                                        - sapbits_bom_files
# Step: 08-01 - END
# -------------------------------------+---------------------------------------8

# -------------------------------------+---------------------------------------8
# Step: 08-02
# Description:
#
    - name:                             "(pre_checks.yaml) - {{ task_prefix }} - Load the storage account details"
      ansible.builtin.include_role:
        name:                           roles-misc/0.3.sap-installation-media-storage-details
        public:                         true
      tags:
        - 0.3.sap-installation-media-storage-details
# Step: 08-02 - END
# -------------------------------------+---------------------------------------8

# -------------------------------------+---------------------------------------8
# Step: 08-03
# Description:
#
    - name:                             "(pre_checks.yaml) - {{ task_prefix }} - Validate required variable is present and not empty (sapbits_location_base_path)"
      ansible.builtin.assert:
        that:
          - "sapbits_location_base_path is defined"                                 # Has the variable been defined
          - "sapbits_location_base_path | trim | length != 0"                       #   and given a value
        success_msg: |-
                                        sapbits_location_base_path:   {{ sapbits_location_base_path | default('NOT DEFINED') }}
        fail_msg: |-
                                        Please ensure that the details are provided for:
                                        - sapbits_location_base_path

                                        either as a parameter or in the deployer key vault
# Step: 08-03 - END
# -------------------------------------+---------------------------------------8

  vars:
    task_prefix:                        Storage Account validation block
  when:
    - ( ( kv_name          is defined     and   kv_name          | trim | length > 1 ) or
        ( deployer_kv_name is defined     and   deployer_kv_name | trim | length > 1 ) )
# Step: 08 - END
# -------------------------------------+---------------------------------------8

- name:                                 "(pre_checks.yaml) - {{ task_prefix }} - Get account information"
  ansible.builtin.command: >-
                                        az account show --query user --output yaml
  vars:
    task_prefix:                        Storage Account validation
  delegate_to:                          localhost
  register:                             azresult
  ignore_errors:                        true
  changed_when:                         false

- name:                                 "(pre_checks.yaml) - {{ task_prefix }} - Show account information"
  ansible.builtin.debug:
    var:                                azresult

# -------------------------------------+---------------------------------------8
# Step: 09
# Description:
#
- name:                                 "(pre_checks.yaml) - Set SAS Token"
  ansible.builtin.set_fact:
    sapbits_sas_token:                  "{{ sapbits_access_key }}"
  no_log:                               true                                    # censor output of secret
  when:
    - sapbits_access_key  is      defined
    - sapbits_sas_token   is not  defined
# Step: 09 - END
# -------------------------------------+---------------------------------------8


# -------------------------------------+---------------------------------------8
# Step: 10
# Description:
#
- name:                                 "(pre_checks.yaml) - Set sa_enabled: true"
  ansible.builtin.set_fact:
    sa_enabled:                         true
  when:
    - "sapbits_location_base_path is defined"                                 # Has the variable been defined
    - "sapbits_location_base_path | trim | length != 0"                       #  and given a value
    - not allowSharedKeyAccess or (sapbits_sas_token is defined and (sapbits_sas_token | trim | length != 0))
    # - "sapbits_access_key         is defined"                                 # Has the variable been defined
    # - "sapbits_access_key         | trim | length != 0"                       #  and given a value

    # - "sapbits_sas_token          is defined"                                 # Has the variable been defined
    # - "sapbits_sas_token          | trim | length != 0"                       #  and given a value
# Step: 10 - END
# -------------------------------------+---------------------------------------8


# -------------------------------------+---------------------------------------8
# Step: 11
# Description:
#
- name:                                 "(pre_checks.yaml) - {{ task_prefix }} - Check storage account container when using SAS Token"
  ansible.builtin.command: >-
                                        az storage blob upload
                                          --account-name {{ sapbits_location_base_path.rpartition('//')[2].split('.')[0] }}
                                          --sas-token {{ sapbits_sas_token }}
                                          --container-name {{ sapbits_location_base_path.rpartition('//')[2].split('/')[1] }}/{{ sapbits_bom_files }}/archives
                                          --name readme.md
                                          --file {{ readme_file.dest }}
                                          --if-none-match "*"
                                          --no-progress
  vars:
    task_prefix:                        Storage Account validation
  delegate_to:                          localhost
  register:                             azresult
  ignore_errors:                        true
  changed_when:                         false
  failed_when:
    - azresult.rc != 0
    - azresult.stderr is defined
    - azresult.stderr.find("BlobAlreadyExists") == -1
  no_log:                               true                                    # censor output of secret
  when:
    - sa_enabled
    - allowSharedKeyAccess

- name:                                 "(pre_checks.yaml) - {{ task_prefix }} - Check storage account container"
  ansible.builtin.command: >-
                                        az storage blob upload
                                          --account-name {{ sapbits_location_base_path.rpartition('//')[2].split('.')[0] }}
                                          --auth-mode login
                                          --container-name {{ sapbits_location_base_path.rpartition('//')[2].split('/')[1] }}/{{ sapbits_bom_files }}/archives
                                          --name readme.md
                                          --file {{ readme_file.dest }}
                                          --if-none-match "*"
                                          --no-progress
  vars:
    task_prefix:                        Storage Account validation
  delegate_to:                          localhost
  register:                             azresult
  ignore_errors:                        true
  changed_when:                         false
  failed_when:
    - azresult.rc != 0
    - azresult.stderr is defined
    - azresult.stderr.find("BlobAlreadyExists") == -1
  no_log:                               true                                    # censor output of secret
  when:
    - sa_enabled
    - not allowSharedKeyAccess

# Step: 11 - END
# -------------------------------------+---------------------------------------8


# -------------------------------------+---------------------------------------8
# Step: 12
# Description:  Informational check of Storage Account parameters.
#
#   - sapbits_location_base_path
#   - sapbits_access_key
#   - sapbits_sas_token
- name:                                "(pre_checks.yaml) - Informational check of Storage Account parameters"
  ansible.builtin.assert:
    that:
      - "sapbits_location_base_path is defined"                                 # Has the variable been defined
      - "sapbits_location_base_path | trim | length != 0"                       #  and given a value
    success_msg: |-
                                        Storage Account access ENABLED
                                        sa_enabled:       {{ sa_enabled }}
    fail_msg: |-
                                        Storage Account access DISABLED
                                        sa_enabled:       {{ sa_enabled }}
  failed_when:                         false

- name:                                "Storage account information"
  ansible.builtin.debug:
    msg:                               # Best method for formatting output with Azure Devops Logs
                                       - "Storage account_name:            {{ account_name }}"
                                       - "allowSharedKeyAccess:            {{ allowSharedKeyAccess }}"

- name:                                "(pre_checks.yaml) - Informational check of Storage Account parameters"
  when:                                 allowSharedKeyAccess
  ansible.builtin.assert:
    that:
      - "sapbits_access_key         is defined"                                 # Has the variable been defined
      - "sapbits_access_key         | trim | length != 0"                       #  and given a value

      - "sapbits_sas_token          is defined"                                 # Has the variable been defined
      - "sapbits_sas_token          | trim | length != 0"                       #  and given a value
    success_msg: |-
                                        Storage Account access ENABLED
                                        sa_enabled:       {{ sa_enabled }}
    fail_msg: |-
                                        Storage Account access DISABLED
                                        sa_enabled:       {{ sa_enabled }}
  failed_when:                         false

# Step: 12 - END
# -------------------------------------+---------------------------------------8

...
# /*---------------------------------------------------------------------------8
# |                                   END                                      |
# +------------------------------------4--------------------------------------*/
