# This workflow should cleanup everything unneeded from the template project

name: Template Janitor

on:
  pull_request:
  release:
    types: [published]
  push:
    tags:
    branches:
      - main
      - develop

env:
  TEMPLATES_PATH: ".github/template"
  CONAN_SYSREQUIRES_MODE: enabled
  CONAN_USER_HOME: "${{ github.workspace }}/conan-cache"
  CONAN_USER_HOME_SHORT: "${{ github.workspace }}/conan-cache/short"
   
jobs:

  template-cleanup:
    name: Cleanup after create
    runs-on: ubuntu-latest
    strategy:
      matrix:
        compiler:
          - gcc-11
        generator:
          - "Unix Makefiles"
        build_type:
          - Debug
        developer_mode:
          - OFF

    steps:
      - uses: actions/checkout@v2

      - name: Setup Cache
        uses: ./.github/actions/setup_cache
        with:
          compiler: ${{ matrix.compiler }}
          build_type: ${{ matrix.build_type }}
          developer_mode: ${{ matrix.developer_mode }}
          generator: ${{ matrix.generator }}

      - name: Get organization and project name 
        run: |
          echo "NEW_ORG=${{ github.repository_owner }}" >> $GITHUB_ENV
          echo "NEW_PROJECT=${{ github.event.repository.name }}" >> $GITHUB_ENV
          echo "NEW_URL=${{ github.repositoryUrl }}" >> $GITHUB_ENV

      - uses: octokit/request-action@v2.x
        id: get_repo_meta
        with:
          route: GET /repos/{owner}/{repo}
          owner: ${{ env.NEW_ORG }}
          repo: ${{ env.NEW_PROJECT }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Use testing variables if still a template
        if: fromJson(steps.get_repo_meta.outputs.data).is_template == true
        run: |
          # This name is unsafe because it is not a valid C++ identifier
          echo "NEW_PROJECT=my-unsafe.project" >> $GITHUB_ENV

      - name: Add safe replacement variable versions
        run: |
          # hyphens and dots in c++ identifiers are forbidden. Use underscores instead.
          NEW_SAFE_PROJECT=$(echo ${{ env.NEW_PROJECT }} | sed "s/-/_/g" | sed "s/\./_/g" )
          echo "NEW_SAFE_PROJECT=$NEW_SAFE_PROJECT" >> $GITHUB_ENV 

      # Rename all cpp_starter_project occurences to current repository and remove this workflow
      - name: Insert new org and project
        run: |
          # rename the CMake project to match the github project
          sed -i "s/myproject/${{ env.NEW_SAFE_PROJECT }}/gi" CMakeLists.txt configured_files/config.hpp.in src/main.cpp test/CMakeLists.txt fuzz_test/CMakeLists.txt

          # Update URL placeholders for project
          sed -i "s|%%myurl%%|${{ fromJson(steps.get_repo_meta.outputs.data).html_url }}|gi" CMakeLists.txt

          # fill in placeholders of readme and move it into place
          sed -i "s/%%myorg%%/${{ env.NEW_ORG }}/g" ${{ env.TEMPLATES_PATH }}/README.md
          sed -i "s/%%myproject%%/${{ env.NEW_PROJECT }}/g" ${{ env.TEMPLATES_PATH }}/README.md
          sed -i "s|%%description%%|${{ fromJson(steps.get_repo_meta.outputs.data).description }}|g" ${{ env.TEMPLATES_PATH }}/README.md
          cp ${{ env.TEMPLATES_PATH }}/README.md README.md

      - name: Print diff after replacement
        run: |
          # Exclude the README as that is checked separately!
          git diff ':!README.md'
          # following should not have any diffs
          diff ${{ env.TEMPLATES_PATH }}/README.md README.md

      - name: Remove unwanted files
        run: |
          # No tests needed as this will fail if any file from the list is missing/misspelled
          xargs rm -r < ${{ env.TEMPLATES_PATH }}/removal-list

      - name: Clean up before commit and push
        run: |
          rm -r ${{ env.TEMPLATES_PATH }}

          # Can we get that from a variable?
          # Remove this workflow as it has fulfilled its purpose
          rm .github/workflows/template-janitor.yml

      - name: Setup Cpp
        uses: aminya/setup-cpp@v1
        with:
          compiler: ${{ matrix.compiler }}

          cmake: true
          ninja: false
          conan: true
          vcpkg: false
          ccache: false
          clangtidy: false

          cppcheck: false

          gcovr: false
          opencppcoverage: false

      - name: Cleanup Conan system packages (they are not properly cached)
        run: |
          conan remove -f '*/system'

      - name: Test simple configuration to make sure nothing broke
        run: |
          cmake -S . -B ./build -G "${{ matrix.generator }}" -DCMAKE_BUILD_TYPE:STRING=${{ matrix.build_type }} -DENABLE_DEVELOPER_MODE:BOOL=${{ matrix.developer_mode }} -DOPT_ENABLE_COVERAGE:BOOL=OFF
          # Build it because we may have broken something in the cpp/hpp files
          cmake --build build

      - uses: EndBug/add-and-commit@v4
        # only commit and push if we are not a template project anymore!
        if: fromJson(steps.get_repo_meta.outputs.data).is_template != true
        with:
          author_name: Template Janitor
          author_email: template.janitor@example.com
          message: 'Cleanup template and initialize repository'
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}



  template-rename:
    name: Renames template when a new name is detected
    runs-on: ubuntu-latest
    strategy:
      matrix:
        compiler:
          - gcc-11
        generator:
          - "Unix Makefiles"
        build_type:
          - Debug
        developer_mode:
          - OFF

    steps:
      - uses: actions/checkout@v2

      - name: Setup Cache
        uses: ./.github/actions/setup_cache
        with:
          compiler: ${{ matrix.compiler }}
          build_type: ${{ matrix.build_type }}
          developer_mode: ${{ matrix.developer_mode }}
          generator: ${{ matrix.generator }}

      - name: Get organization and project name 
        run: |
          echo "TEST_RUN=false" >> $GITHUB_ENV
          echo "NEW_ORG=${{ github.repository_owner }}" >> $GITHUB_ENV
          echo "NEW_PROJECT=${{ github.event.repository.name }}" >> $GITHUB_ENV
          echo "NEW_REPOSITORY=${{ github.repository }}" >> $GITHUB_ENV
          echo "TEMPLATE_NAME=`cat ${{ env.TEMPLATES_PATH }}/template_name`" >> $GITHUB_ENV
          echo "TEMPLATE_REPOSITORY=`cat ${{ env.TEMPLATES_PATH }}/template_repository`" >> $GITHUB_ENV

      - uses: octokit/request-action@v2.x
        id: get_repo_meta
        with:
          route: GET /repos/{owner}/{repo}
          owner: ${{ env.NEW_ORG }}
          repo: ${{ env.NEW_PROJECT }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Setup fake test org/project names if project didn't change
        if: env.TEMPLATE_NAME == env.NEW_PROJECT
        run: |
          echo "TEST_RUN=true" >> $GITHUB_ENV
          echo "NEW_ORG=${{ github.repository_owner }}" >> $GITHUB_ENV
          echo "NEW_PROJECT=TEST_PROJECT" >> $GITHUB_ENV
          echo "NEW_REPOSITORY=TEST_REPOSITORY" >> $GITHUB_ENV


      # Rename all cpp_starter_project occurrences to current repository and remove this workflow
      - name: Update repository to match new template information
        run: |
          # Update the README and template files to match the new org / repository names 
          sed -i "s|${{ env.TEMPLATE_REPOSITORY }}|${{ env.NEW_REPOSITORY }}|g" README.md ${{ env.TEMPLATES_PATH }}/template_repository
          sed -i "s|${{ env.TEMPLATE_NAME }}|${{ env.NEW_PROJECT }}|g" README.md ${{ env.TEMPLATES_PATH }}/template_name

      - name: Print diff after template name replacement
        run: |
          git diff

      - name: Setup Cpp
        uses: aminya/setup-cpp@v1
        with:
          compiler: gcc

          cmake: true
          ninja: false
          conan: true
          vcpkg: false
          ccache: false
          clangtidy: false

          cppcheck: false

          gcovr: false
          opencppcoverage: false

      - name: Cleanup Conan system packages (they are not properly cached)
        run: |
          conan remove -f '*/system'

      - name: Test simple configuration to make sure nothing broke (default compiler,cmake,developer_mode OFF)
        run: |
          cmake -S . -B ./build -G "${{ matrix.generator }}" -DCMAKE_BUILD_TYPE:STRING=${{ matrix.build_type }} -DENABLE_DEVELOPER_MODE:BOOL=${{ matrix.developer_mode }} -DOPT_ENABLE_COVERAGE:BOOL=OFF

      - uses: EndBug/add-and-commit@v4
        # only commit and push if we are a template and project name has changed
        if: fromJson(steps.get_repo_meta.outputs.data).is_template == true && env.TEST_RUN == 'false'
        with:
          author_name: Template Janitor
          author_email: template.janitor@example.com
          message: 'Change Template Name'
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
