on:
  workflow_call:
    inputs:
      test-entry-point:
        description: 'Test entry point'
        required: false
        type: string
        default: '' # empty string means run all tests
      temp-run-full-suite:
        description: 'This flag exists to run a hard coded set of tests and will be phased out'
        required: false
        type: boolean
        default: false
      test:
        description: 'test name to run as standalone'
        required: false
        type: string
        default: ''
      test-exclusions:
        description: 'Comma separated list of tests to skip'
        required: false
        type: string
        default: '' # empty string means don't skip any test.
      chain-image:
        description: 'The image to use for chains'
        required: false
        type: string
        default: 'ghcr.io/cosmos/ibc-go-simd'
      chain-a-tag:
        description: 'The tag to use for chain A'
        required: true
        type: string
        default: main
      chain-b-tag:
        default: main
        description: 'The tag to use for chain B'
        required: true
        type: string
      # upgrade-plan-name is only required during upgrade tests, and is otherwise ignored.
      upgrade-plan-name:
        default: ''
        description: 'The upgrade plan name'
        required: false
        type: string
      build-and-push-docker-image:
        description: 'Flag to specify if the docker image should be built and pushed beforehand'
        required: false
        type: boolean
        default: false
      build-and-push-docker-image-wasm:
        description: 'Flag to specify if the wasm docker image should be built and pushed beforehand'
        required: false
        type: boolean
        default: false
      upload-logs:
        description: 'Specify flag to indicate that logs should be uploaded on failure'
        required: false
        type: boolean
        default: false
      e2e-config-path:
        description: 'Specify relative or absolute path of config file for test'
        required: false
        type: string
        default: 'ci-e2e-config.yaml'

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ibc-go-simd
  IMAGE_NAME_WASM: ibc-go-wasm-simd

jobs:
  # test-details exists to provide an easy way to see the inputs for the e2e test.
  test-details:
    runs-on: depot-ubuntu-22.04-4
    steps:
      - name: Display Inputs
        run: |
          echo "Chain Image:       ${{ inputs.chain-image }}"
          echo "Chain A Tag:       ${{ inputs.chain-a-tag }}"
          echo "Chain B Tag:       ${{ inputs.chain-b-tag }}"
          echo "Upgrade Plan Name: ${{ inputs.upgrade-plan-name }}"
          echo "Test Entry Point:  ${{ inputs.test-entry-point }}"
          echo "Test:              ${{ inputs.test }}"
          echo "Github Ref Name:   ${{ github.ref_name }}"

  # we skip individual steps rather than the full job as e2e-tests will not run if this task
  # is skipped. But will run if every individual task is skipped. There is no current way of conditionally needing
  # a job.
  docker-build:
    runs-on: depot-ubuntu-22.04-4
    steps:
      - uses: actions/checkout@v4
        if: ${{ inputs.build-and-push-docker-image }}
      - name: Log in to the Container registry
        if: ${{ inputs.build-and-push-docker-image }}
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata (tags, labels) for Docker
        if: ${{ inputs.build-and-push-docker-image }}
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/cosmos/${{ env.IMAGE_NAME }}

      - name: Build and push Docker image
        if: ${{ inputs.build-and-push-docker-image }}
        uses: docker/build-push-action@v6
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          build-args: |
            IBC_GO_VERSION=${{ github.ref_name }}

  docker-build-wasm:
    runs-on: depot-ubuntu-22.04-4
    steps:
      - uses: actions/checkout@v4
        if: ${{ inputs.build-and-push-docker-image-wasm }}

      - uses: actions/setup-python@v5
        if: ${{ inputs.build-and-push-docker-image-wasm }}
        with:
          python-version: '3.10'

      - name: Install dependencies
        if: ${{ inputs.build-and-push-docker-image-wasm }}
        run: make python-install-deps

      - name: Determine Build arguments
        if: ${{ inputs.build-and-push-docker-image-wasm }}
        id: build-args
        run: |
          echo "version=$(scripts/get-libwasm-version.py --get-version)" >> $GITHUB_OUTPUT
          echo "checksum=$(scripts/get-libwasm-version.py --get-checksum)" >> $GITHUB_OUTPUT

      - name: Log in to the Container registry
        if: ${{ inputs.build-and-push-docker-image-wasm }}
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata (tags, labels) for Docker
        if: ${{ inputs.build-and-push-docker-image-wasm }}
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/cosmos/${{ env.IMAGE_NAME_WASM }}

      - name: Build and push Docker image
        if: ${{ inputs.build-and-push-docker-image-wasm }}
        uses: docker/build-push-action@v6
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          file: modules/light-clients/08-wasm/Dockerfile
          build-args: |
            LIBWASM_VERSION=${{ steps.build-args.outputs.version }}
            LIBWASM_CHECKSUM=${{ steps.build-args.outputs.checksum }}


  # dynamically build a matrix of test/test suite pairs to run.
  # this job runs a go tool located at cmd/build_test_matrix/main.go.
  # it walks the e2e/test directory in order to locate all test suite / test name
  # pairs. The output of this job can be fed in as input to a workflow matrix and
  # will expand to jobs which will run all tests present.
  build-test-matrix:
    runs-on: depot-ubuntu-22.04-4
    outputs:
      matrix: ${{ steps.set-matrix.outputs.matrix }}
    steps:
      - uses: actions/checkout@v4
        with:
          repository: cosmos/ibc-go
      - uses: actions/setup-go@v5
        with:
          go-version: '1.23'
      - id: set-matrix
        run: |
          output=$(go run cmd/build_test_matrix/main.go)
          echo "matrix=$output" >> $GITHUB_OUTPUT
        env:
          TEST_ENTRYPOINT: '${{ inputs.test-entry-point }}'
          TEST_EXCLUSIONS: '${{ inputs.test-exclusions }}'
          TEST_NAME: '${{ inputs.test }}'

  # e2e-tests runs the actual go test command to trigger the test.
  # the tests themselves are configured via environment variables to specify
  # things like chain and relayer images and tags.
  e2e-tests:
    runs-on: depot-ubuntu-22.04-4
    needs:
      - build-test-matrix
      - docker-build
      - docker-build-wasm
    env:
      CHAIN_IMAGE: '${{ inputs.chain-image }}'
      CHAIN_UPGRADE_PLAN: '${{ inputs.upgrade-plan-name }}'
      CHAIN_A_TAG: '${{ inputs.chain-a-tag }}'
      CHAIN_B_TAG: '${{ inputs.chain-b-tag }}'
      E2E_CONFIG_PATH: '${{ inputs.e2e-config-path }}'
    strategy:
      fail-fast: false
      matrix: ${{ fromJSON(needs.build-test-matrix.outputs.matrix) }}
    steps:
      - uses: actions/checkout@v4
        with:
          repository: cosmos/ibc-go
      - uses: actions/setup-go@v5
        with:
          go-version: '1.23'
          cache-dependency-path: 'e2e/go.sum'
      - name: Run e2e Test
        id: e2e_test
        run: |
          cd e2e
          make e2e-test test=${{ matrix.test }}
      - name: Upload Diagnostics
        uses: actions/upload-artifact@v4
        if: ${{ failure() && inputs.upload-logs }}
        continue-on-error: true
        with:
          name: '${{ matrix.entrypoint }}-${{ matrix.test }}'
          path: e2e/diagnostics
          retention-days: 5

  e2e-test-suites:
    # temporary flag. eventually this field will not exist and this will be the default.
    if: ${{ inputs.temp-run-full-suite }}
    runs-on: depot-ubuntu-22.04-4
    needs:
      - build-test-matrix
      - docker-build
      - docker-build-wasm
    env:
      CHAIN_IMAGE: '${{ inputs.chain-image }}'
      CHAIN_A_TAG: '${{ inputs.chain-a-tag }}'
      CHAIN_B_TAG: '${{ inputs.chain-b-tag }}'
      E2E_CONFIG_PATH: '${{ inputs.e2e-config-path }}'
    strategy:
      fail-fast: false
      matrix:
        include:
            # for now we explicitly specify this test suite.
          - entrypoint: TestTransferTestSuite
          - entrypoint: TestAuthzTransferTestSuite
          - entrypoint: TestTransferTestSuiteSendReceive
          - entrypoint: TestTransferTestSuiteSendEnabled
          - entrypoint: TestTransferLocalhostTestSuite
          - entrypoint: TestConnectionTestSuite
          - entrypoint: TestInterchainAccountsGovTestSuite
    steps:
      - uses: actions/checkout@v4
        with:
          repository: cosmos/ibc-go
      - uses: actions/setup-go@v5
        with:
          go-version: '1.23'
          cache-dependency-path: 'e2e/go.sum'
      - name: Run e2e Test
        id: e2e_test
        run: |
          cd e2e
          make e2e-suite entrypoint=${{ matrix.entrypoint }}
      - name: Upload Diagnostics
        uses: actions/upload-artifact@v4
        if: ${{ failure() && inputs.upload-logs }}
        continue-on-error: true
        with:
          name: '${{ matrix.entrypoint }}-${{ matrix.test }}'
          path: e2e/diagnostics
          retention-days: 5
