on:
  workflow_call:
    inputs:
      version_file:
        required: false
        type: string
        default: CMakeLists.txt
    outputs:
      latest_major_version:
        description: "latest major version"
        value: ${{ jobs.get-environment.outputs.latest_major_version }}
      is_cloud:
        description: "context of release (cloud or not cloud)"
        value: ${{ jobs.get-environment.outputs.is_cloud }}
      major_version:
        description: "major version"
        value: ${{ jobs.get-environment.outputs.major_version }}
      minor_version:
        description: "minor version"
        value: ${{ jobs.get-environment.outputs.minor_version }}
      release:
        description: "release"
        value: ${{ jobs.get-environment.outputs.release }}
      stability:
        description: "branch stability (stable, testing, unstable, canary)"
        value: ${{ jobs.get-environment.outputs.stability }}
      target_stability:
        description: "Final target branch stability (stable, testing, unstable, canary or not defined if not a pull request)"
        value: ${{ jobs.get-environment.outputs.target_stability }}
      release_type:
        description: "type of release (hotfix, release or not defined if not a release)"
        value: ${{ jobs.get-environment.outputs.release_type }}
      is_targeting_feature_branch:
        description: "if it is a PR, check if targeting a feature branch"
        value: ${{ jobs.get-environment.outputs.is_targeting_feature_branch }}
      img_version:
        description: "docker image version (vcpkg checksum)"
        value: ${{ jobs.get-environment.outputs.img_version }}
      test_img_version:
        description: "test docker image version (checksum of database sql, script and dockerfiles)"
        value: ${{ jobs.get-environment.outputs.test_img_version }}
      gorgone_docker_version:
        description: "md5 of gorgone dockerfile"
        value: ${{ jobs.get-environment.outputs.gorgone_docker_version }}

jobs:
  get-environment:
    runs-on: ubuntu-24.04
    outputs:
      latest_major_version: ${{ steps.latest_major_version.outputs.latest_major_version }}
      is_cloud: ${{ steps.detect_cloud_version.outputs.result }}
      major_version: ${{ steps.get_version.outputs.major_version }}
      minor_version: ${{ steps.get_version.outputs.minor_version }}
      release: ${{ steps.get_release.outputs.release }}
      stability: ${{ steps.get_stability.outputs.stability }}
      target_stability: ${{ steps.get_stability.outputs.target_stability }}
      release_type: ${{ steps.get_release_type.outputs.release_type }}
      is_targeting_feature_branch: ${{ steps.get_stability.outputs.is_targeting_feature_branch }}
      img_version: ${{ steps.get_docker_images_version.outputs.img_version }}
      test_img_version: ${{ steps.get_docker_images_version.outputs.test_img_version }}
      gorgone_docker_version: ${{ steps.get_docker_images_version.outputs.gorgone_docker_version }}

    steps:
      - name: Checkout sources (current branch)
        uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0

      # get latest major version to detect cloud / on-prem versions
      - name: Checkout sources (develop branch)
        uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
        with:
          ref: develop
          path: centreon-develop
          sparse-checkout: .version

      - name: Store latest major version
        id: latest_major_version
        run: |
          . centreon-develop/.version
          echo "latest_major_version=$MAJOR" >> $GITHUB_OUTPUT
        shell: bash

      - if: ${{ github.event_name == 'pull_request' }}
        name: Get nested pull request path
        id: pr_path
        uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
        with:
          script: |
            const prPath = ['${{ github.head_ref }}', '${{ github.base_ref }}'];

            const result = await github.rest.pulls.list({
              owner: context.repo.owner,
              repo: context.repo.repo,
              per_page: 100,
              state: 'open'
            });

            let found = true;
            while (found) {
              found = false;
              result.data.forEach(({ head: { ref: headRef }, base: { ref: baseRef} }) => {
                if (headRef === prPath[prPath.length - 1] && ! prPath.includes(baseRef)) {
                  found = true;
                  prPath.push(baseRef);
                }
              });
            }

            return prPath;

      - name: Get stability
        id: get_stability
        uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
        with:
          script: |
            const getStability = (branchName) => {
              switch (true) {
                case /(^develop$)|(^dev-\d{2}\.\d{2}\.x$)|(^prepare-release-cloud.*)/.test(branchName):
                  return 'unstable';
                case /(^release.+)|(^hotfix.+)/.test(branchName):
                  return 'testing';
                case /(^master$)|(^\d{2}\.\d{2}\.x$)/.test(branchName):
                  return 'stable';
                default:
                  return 'canary';
              }
            };

            core.setOutput('stability', getStability('${{ github.head_ref || github.ref_name }}'));

            let isTargetingFeatureBranch = false;
            if ("${{ github.event_name }}" === "pull_request") {
              let targetStability = 'canary';
              const prPath = ${{ steps.pr_path.outputs.result || '[]' }};
              prPath.shift(); // remove current branch

              if (prPath.length && getStability(prPath[0]) === 'canary') {
                isTargetingFeatureBranch = true;
              }

              prPath.every((branchName) => {
                console.log(`checking stability of ${branchName}`)
                targetStability = getStability(branchName);

                if (targetStability !== 'canary') {
                  return false;
                }

                return true;
              });

              core.setOutput('target_stability', targetStability);
            }

            core.setOutput('is_targeting_feature_branch', isTargetingFeatureBranch);

      - name: Get version from ${{ inputs.version_file }}
        id: get_version
        run: |
          if [[ "${{ inputs.version_file }}" == */.version ]]; then
            . .version
            . ${{ inputs.version_file }}
            VERSION="$MAJOR.$MINOR"
          elif [[ "${{ inputs.version_file }}" == CMakeLists.txt ]]; then
            MAJOR=$(awk '$1 ~ "COLLECT_MAJOR" {maj=substr($2, 1, length($2)-1)} $1 ~ "COLLECT_MINOR" {min=substr($2, 1, length($2)-1) ; print maj "." min}' CMakeLists.txt)
            MINOR=$(awk '$1 ~ "COLLECT_PATCH" {print substr($2, 1, length($2) - 1)}' CMakeLists.txt)
            VERSION="$MAJOR.$MINOR"
          else
            echo "Unable to parse version file ${{ inputs.version_file }}"
            exit 1
          fi

          if grep -E '^[2-9][0-9]\.[0-9][0-9]\.[0-9]+' <<<"$VERSION" >/dev/null 2>&1 ; then
            n=${VERSION//[!0-9]/ }
            a=(${n//\./ })
            echo "major_version=${a[0]}.${a[1]}" >> $GITHUB_OUTPUT
            MAJOR=${a[0]}.${a[1]}
            echo "minor_version=${a[2]}" >> $GITHUB_OUTPUT
          else
            echo "Cannot parse version number from ${{ inputs.version_file }}"
            exit 1
          fi
        shell: bash

      - name: "Get release: 1 for testing / stable, <date>.<commit_sha> for others"
        id: get_release
        run: |
          if [[ "${{ steps.get_stability.outputs.stability }}" == "testing" || "${{ steps.get_stability.outputs.stability }}" == "stable" ]]; then
            RELEASE="1"
          else
            RELEASE="$(date +%s).$(echo ${{ github.sha }} | cut -c -7)"
          fi

          echo "release=$RELEASE" >> $GITHUB_OUTPUT
        shell: bash

      - name: "Get release type: hotfix, release or not defined if not a release"
        id: get_release_type
        run: |
          RELEASE_TYPE=$(echo "${{ github.head_ref || github.ref_name }}" | cut -d '-' -f 1)
          if [[ "$RELEASE_TYPE" == "hotfix" || "$RELEASE_TYPE" == "release" ]]; then
            echo "release_type=$RELEASE_TYPE" >> $GITHUB_OUTPUT
          fi
        shell: bash

      - name: "Detect cloud version"
        id: detect_cloud_version
        uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
        with:
          script: |
            if ("${{ github.ref_name }}" === "master") {
              return true;
            }

            if ("${{ github.event_name }}" === "pull_request") {
              const prPath = ${{ steps.pr_path.outputs.result || '[]' }};
              const finalTargetBranch = prPath.pop();
              if (['develop', 'master'].includes(finalTargetBranch)) {
                return true;
              } else if (/\d{2}\.\d{2}\.x$/.test(finalTargetBranch)) {
                return false;
              }
            }

            const developMajorVersion = "${{ steps.latest_major_version.outputs.latest_major_version }}";
            const currentMajorVersion = "${{ steps.get_version.outputs.major_version }}";

            if (Number(currentMajorVersion) >= Number(developMajorVersion)) {
              return true;
            }

            return false;

      - name: Get docker images version
        id: get_docker_images_version
        run: |
          IMG_VERSION=$( cat `ls .github/docker/Dockerfile.centreon-collect-* | grep -v test` vcpkg.json | md5sum | awk '{print substr($1, 0, 8)}')
          echo "img_version=$IMG_VERSION" >> $GITHUB_OUTPUT

          TEST_IMG_VERSION=$(cat .github/docker/Dockerfile.centreon-collect-*-test .github/scripts/collect-prepare-test-robot.sh resources/*.sql | md5sum | cut -c1-8)
          echo "test_img_version=$TEST_IMG_VERSION" >> $GITHUB_OUTPUT

          GORGONE_DOCKER_VERSION=$(cat .github/docker/Dockerfile.gorgone-testing-* | md5sum | cut -c1-8)
          echo "gorgone_docker_version=$GORGONE_DOCKER_VERSION" >> $GITHUB_OUTPUT

      - name: Display info in job summary
        uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
        env:
          VERSION_FILE: ${{ inputs.version_file }}
        with:
          script: |
            const outputTable = [
              [{data: 'Name', header: true}, {data: 'Value', header: true}],
              ['latest_major_version', '${{ steps.latest_major_version.outputs.latest_major_version }}'],
              ['is_cloud', '${{ steps.detect_cloud_version.outputs.result }}'],
              ['major_version', '${{ steps.get_version.outputs.major_version }}'],
              ['minor_version', '${{ steps.get_version.outputs.minor_version }}'],
              ['release', '${{ steps.get_release.outputs.release }}'],
              ['stability', '${{ steps.get_stability.outputs.stability }}'],
              ['release_type', '${{ steps.get_release_type.outputs.release_type || '<em>not defined because this is not a release</em>' }}'],
              ['is_targeting_feature_branch', '${{ steps.get_stability.outputs.is_targeting_feature_branch }}'],
              ['img_version', '${{ steps.get_docker_images_version.outputs.img_version }}'],
              ['test_img_version', '${{ steps.get_docker_images_version.outputs.test_img_version }}'],
              ['gorgone_docker_version', '${{ steps.get_docker_images_version.outputs.gorgone_docker_version }}'],
            ];

            outputTable.push(['target_stability', '${{ steps.get_stability.outputs.target_stability || '<em>not defined because current run is not triggered by pull request event</em>' }}']);

            core.summary
              .addHeading(`${context.workflow} environment outputs`)
              .addTable(outputTable);

            if ("${{ github.event_name }}" === "pull_request") {
              const prPath = ${{ steps.pr_path.outputs.result || '[]' }};
              const mainBranchName = prPath.pop();
              let codeBlock = `
                %%{ init: { 'gitGraph': { 'mainBranchName': '${mainBranchName}', 'showCommitLabel': false } } }%%
                gitGraph
                  commit`;
              prPath.reverse().forEach((branchName) => {
                codeBlock = `${codeBlock}
                  branch ${branchName}
                  checkout ${branchName}
                  commit`;
              });

              core.summary
                .addHeading('Git workflow')
                .addCodeBlock(
                  codeBlock,
                  "mermaid"
                );
            }

            core.summary.write();
