---
#
#  Author: Michael De La Rue
#  based on ec2_key.yml + lambda.py

- block:

    # ============================================================
    - name: test with no parameters
      lambda_policy:
      register: result
      ignore_errors: true

    - name: assert failure when called with no parameters
      assert:
        that:
           - 'result.failed'
           - 'result.msg.startswith("missing required arguments: ")'

    # ============================================================
    - name: test with all required dummy parameters but no region
      lambda_policy:
        statement_id: dummy
        principal: api_fakeway
        action: fake:do_something_fake
        function_name: dummy_fake_function
      ignore_errors: true
      register: result

    - name: assert failure and appropriate message when called without region
      assert:
        that:
           - 'result.failed'
           - '"region must be specified" in result.msg'

    # ============================================================
    - name: test with all required dummy parameters but no region
      lambda_policy:
        statement_id: dummy
        principal: api_fakeway
        action: fake:do_something_fake
        function_name: dummy_fake_function
        region: null
      ignore_errors: true
      register: result

    - name: assert failure and appropriate message when called false region region
      assert:
        that:
           - 'result.failed'
           - '"region must be specified" in result.msg'

    # ============================================================
    - name: test exceptions generated by forcing bad ec2 url
      lambda_policy:
        function_name: "{{ lambda_function_name }}"
        region: "{{ec2_region}}"
        state: present
        statement_id: api-gateway-invoke-lambdas
        action: lambda:InvokeFunction
        principal: apigateway.amazonaws.com
        source_arn: "arn:aws:execute-api:no-north-0:1234567:*/*"
        ec2_url: https://noexist.example.com
        ec2_region: 'no-north-0'
        ec2_access_key: 'iamnotreallyanaccesskey'
        ec2_secret_key: 'thisisabadsecretkey'
        security_token: 'andthisisabadsecuritytoken'
      register: result
      ignore_errors: true

    - name: assert lambda manages to respond as expected
      assert:
        that:
           - 'result|failed'
           - 'result.msg != "MODULE FAILURE"'
           - 'result.changed == False'

    # ============================================================
    # direct zip file upload
    - name: move lambda into place for archive module
      copy:
        src: "mini_http_lambda.py"
        dest: "{{output_dir}}/mini_http_lambda.py"

    - name: bundle lambda into a zip
      archive:
        format: zip
        path: "{{output_dir}}/mini_http_lambda.py"
        dest: "{{output_dir}}/mini_http_lambda.zip"
      register: zip_res

    - name: test state=present - upload the lambda
      lambda:
        name="{{lambda_function_name}}"
        runtime="python2.7"
        handler="mini_http_lambda.handler"
        role="ansible_lambda_role"
        ec2_region='{{ec2_region}}'
        aws_access_key='{{aws_access_key}}'
        aws_secret_key='{{aws_secret_key}}'
        security_token='{{security_token}}'
        zip_file="{{zip_res.dest}}"
      register: lambda_result

    - name: install aws cli - FIXME temporary this should go for a lighterweight solution
      command: pip install awscli
      register: result

    - name: get the aws account ID for use in future commands
      command: aws sts get-caller-identity --output text --query 'Account'
      environment:
          AWS_ACCESS_KEY_ID: '{{aws_access_key}}'
          AWS_SECRET_ACCESS_KEY: '{{aws_secret_key}}'
          AWS_SESSION_TOKEN: '{{security_token}}'
      register: result

    - name: register account id
      set_fact:
        aws_account_id: "{{ result.stdout | replace('\n', '') }}"

    - name: register lambda uri for use in template
      set_fact:
        mini_lambda_uri: "arn:aws:apigateway:{{ec2_region}}:lambda:path/2015-03-31/functions/arn:aws:lambda:{{ec2_region}}:{{aws_account_id}}:function:{{ lambda_result.configuration.function_name }}/invocations"

    - name: build API file
      template:
        src: endpoint-test-swagger-api.yml.j2
        dest: "{{output_dir}}/endpoint-test-swagger-api.yml.j2"

    - name: deploy new API
      aws_api_gateway:
        api_file: "{{output_dir}}/endpoint-test-swagger-api.yml.j2"
        stage: "lambdabased"
        region: '{{ec2_region}}'
        aws_access_key: '{{aws_access_key}}'
        aws_secret_key: '{{aws_secret_key}}'
        security_token: '{{security_token}}'
      register: create_result


    - name: register api id for later
      set_fact:
        api_id: "{{ create_result.api_id }}"

    - name: check API fails with permissions failure
      uri: url="https://{{create_result.api_id}}.execute-api.{{ec2_region}}.amazonaws.com/lambdabased/mini/Mr_Ansible_Tester"
      register: unauth_uri_result
      ignore_errors: true

    - name: assert internal server error due to permissions
      assert:
        that:
          - unauth_uri_result|failed
          - 'unauth_uri_result.status == 500'

    - name: give api gateway execute permissions on lambda
      lambda_policy:
        function_name: "{{ lambda_function_name }}"
        region: "{{ec2_region}}"
        state: present
        statement_id: api-gateway-invoke-lambdas
        action: lambda:InvokeFunction
        principal: apigateway.amazonaws.com
        source_arn: "arn:aws:execute-api:{{ ec2_region }}:{{ aws_account_id }}:*/*"
        aws_access_key: '{{aws_access_key}}'
        aws_secret_key: '{{aws_secret_key}}'
        security_token: '{{security_token}}'

    - name: check API works with execute permissions
      uri: url="https://{{create_result.api_id}}.execute-api.{{ec2_region}}.amazonaws.com/lambdabased/mini/Mr_Ansible_Tester"
      register: uri_result

    - name: assert API works success
      assert:
        that:
           - 'uri_result'


    - name: deploy new API
      aws_api_gateway:
        api_file: "{{output_dir}}/endpoint-test-swagger-api.yml.j2"
        stage: "lambdabased"
        region: '{{ec2_region}}'
        aws_access_key: '{{aws_access_key}}'
        aws_secret_key: '{{aws_secret_key}}'
        security_token: '{{security_token}}'
      register: create_result
      ignore_errors: true


  always:

    # ============================================================
    - name: destroy lambda for test cleanup if created
      lambda:
        name="{{lambda_function_name}}"
        ec2_region='{{ec2_region}}'
        ec2_access_key='{{ec2_access_key}}'
        ec2_secret_key='{{ec2_secret_key}}'
        security_token='{{security_token}}'
        state=absent
      register: result

    - name: destroy API for test cleanup if created
      aws_api_gateway:
        state: absent
        api_id: '{{api_id}}'
        region: '{{ec2_region}}'
        aws_access_key: '{{ec2_access_key}}'
        aws_secret_key: '{{ec2_secret_key}}'
        security_token: '{{security_token}}'
      register: destroy_result

    - name: assert destroy statements succeeded
      assert:
        that:
           - 'destroy_result.changed == True'
           - 'not result|failed'
