stages:
  - build
  - gitops

variables:
  AWS_REGION: ap-southeast-3
  ECR_REGISTRY: 886436954922.dkr.ecr.ap-southeast-3.amazonaws.com
  ECR_REPO_NAME: mbugroup/lti-api
  ECR_REPOSITORY: ${ECR_REGISTRY}/${ECR_REPO_NAME}
  TARGET_PLATFORM: linux/amd64

  DOCKER_HOST: unix:///var/run/docker.sock
  DOCKER_TLS_CERTDIR: ""
  DOCKER_BUILDKIT: "1"

workflow:
  rules:
    # run untuk branch utama & MR
    - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "development"'
    - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "production"'
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "production"'
    - when: never

# =========================
# Helper: login ECR
# =========================
.ecr_login: &ecr_login |
  AWS_CLI_ENV_ARGS=""
  AWS_CLI_ENV_ARGS="$AWS_CLI_ENV_ARGS -e AWS_REGION=$AWS_REGION"
  AWS_CLI_ENV_ARGS="$AWS_CLI_ENV_ARGS -e AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-}"
  AWS_CLI_ENV_ARGS="$AWS_CLI_ENV_ARGS -e AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-}"
  if [ -n "${AWS_SESSION_TOKEN:-}" ]; then
    AWS_CLI_ENV_ARGS="$AWS_CLI_ENV_ARGS -e AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN"
  fi

  PASS="$(docker run --rm $AWS_CLI_ENV_ARGS public.ecr.aws/aws-cli/aws-cli:latest \
    ecr get-login-password --region "$AWS_REGION" || true)"
  if [ -z "$PASS" ]; then
    echo "ERROR: Failed to get ECR login password."
    exit 1
  fi
  echo "$PASS" | docker login --username AWS --password-stdin "$ECR_REGISTRY"

# =========================
# MR
# =========================
build_mr:
  stage: build
  image: public.ecr.aws/docker/library/docker:27
  tags: [self-hosted-dev]
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "production"'
  variables:
    IMAGE_TAG: "prod-${CI_COMMIT_SHORT_SHA}"
  before_script:
    - set -eu
    - docker version
    - docker info
    - *ecr_login
  script: |
    set -eu
    # force base image pulls via AWS ECR Public to avoid Docker Hub TLS timeout
    sed -i 's|^FROM golang:1.23-alpine AS builder$|FROM public.ecr.aws/docker/library/golang:1.23-alpine AS builder|' Dockerfile
    sed -i 's|^FROM alpine:3.20$|FROM public.ecr.aws/docker/library/alpine:3.20|' Dockerfile
    echo "Build (MR) : $ECR_REPOSITORY:$IMAGE_TAG"
    docker build --platform "$TARGET_PLATFORM" -f Dockerfile -t "$ECR_REPOSITORY:$IMAGE_TAG" .
    echo "Pushing image for MR..."
    docker push "$ECR_REPOSITORY:$IMAGE_TAG"

# =========================
# DEVELOPMENT (push branch development)
# =========================
build_push_dev:
  stage: build
  image: public.ecr.aws/docker/library/docker:27
  tags: [self-hosted-dev]
  rules:
    - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "development"'
  variables:
    IMAGE_TAG: "dev-${CI_COMMIT_SHORT_SHA}"
  before_script:
    - set -eu
    - docker version
    - docker info
    - *ecr_login
  script: |
    set -eu
    # force base image pulls via AWS ECR Public to avoid Docker Hub TLS timeout
    sed -i 's|^FROM golang:1.23-alpine AS builder$|FROM public.ecr.aws/docker/library/golang:1.23-alpine AS builder|' Dockerfile
    sed -i 's|^FROM alpine:3.20$|FROM public.ecr.aws/docker/library/alpine:3.20|' Dockerfile
    echo "Build & push (dev): $ECR_REPOSITORY:$IMAGE_TAG"
    docker build --platform "$TARGET_PLATFORM" -f Dockerfile -t "$ECR_REPOSITORY:$IMAGE_TAG" .
    docker push "$ECR_REPOSITORY:$IMAGE_TAG"

update_gitops_dev_lti:
  stage: gitops
  image: public.ecr.aws/docker/library/alpine:3.20
  tags: [self-hosted-dev]
  rules:
    - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "development"'
  needs: ["build_push_dev"]
  variables:
    IMAGE_TAG: "dev-${CI_COMMIT_SHORT_SHA}"
    GITOPS_BRANCH: main
    VALUES_FILE: environments/lti/dev/lti-values-dev.yaml
    GITOPS_REPO_URL: https://oauth2:${GITOPS_TOKEN}@gitlab.com/cristian.anggita.parjaman/gitops.git
  before_script:
    - set -eu
    - apk add --no-cache git yq
    - git config --global user.email "ci@gitlab"
    - git config --global user.name "gitlab-ci"
  script: |
    set -eu
    rm -rf gitops
    git clone --depth 1 --branch "$GITOPS_BRANCH" "$GITOPS_REPO_URL" gitops
    cd gitops

    echo "Updating dev image.tag to $IMAGE_TAG"
    yq -i '.image.tag = strenv(IMAGE_TAG)' "$VALUES_FILE"

    git add "$VALUES_FILE"
    if git diff --cached --quiet; then
      echo "No changes to commit"
      exit 0
    fi
    git commit -m "lti dev deploy ${IMAGE_TAG}"
    git push origin "$GITOPS_BRANCH"

# =========================
# PRODUCTION (push branch production)
# =========================
build_push_prod:
  stage: build
  image: public.ecr.aws/docker/library/docker:27
  tags: [self-hosted-dev]
  rules:
    - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "production"'
  variables:
    IMAGE_TAG: "prod-${CI_COMMIT_SHORT_SHA}"
  before_script:
    - set -eu
    - docker version
    - docker info
    - *ecr_login
  script: |
    set -eu
    # force base image pulls via AWS ECR Public to avoid Docker Hub TLS timeout
    sed -i 's|^FROM golang:1.23-alpine AS builder$|FROM public.ecr.aws/docker/library/golang:1.23-alpine AS builder|' Dockerfile
    sed -i 's|^FROM alpine:3.20$|FROM public.ecr.aws/docker/library/alpine:3.20|' Dockerfile
    echo "Build & push (prod): $ECR_REPOSITORY:$IMAGE_TAG"
    docker build --platform "$TARGET_PLATFORM" -f Dockerfile -t "$ECR_REPOSITORY:$IMAGE_TAG" .
    docker push "$ECR_REPOSITORY:$IMAGE_TAG"

update_gitops_prod_lti:
  stage: gitops
  image: public.ecr.aws/docker/library/alpine:3.20
  tags: [self-hosted-dev]
  rules:
    - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "production"'
  needs: ["build_push_prod"]
  variables:
    IMAGE_TAG: "prod-${CI_COMMIT_SHORT_SHA}"
    GITOPS_BRANCH: main
    VALUES_FILE: environments/lti/prod/lti-values-prod.yaml
    GITOPS_REPO_URL: https://oauth2:${GITOPS_TOKEN}@gitlab.com/cristian.anggita.parjaman/gitops.git
  before_script:
    - set -eu
    - apk add --no-cache git yq
    - git config --global user.email "ci@gitlab"
    - git config --global user.name "gitlab-ci"
  script: |
    set -eu
    rm -rf gitops
    git clone --depth 1 --branch "$GITOPS_BRANCH" "$GITOPS_REPO_URL" gitops
    cd gitops

    echo "Updating prod image.tag to $IMAGE_TAG"
    yq -i '.image.tag = strenv(IMAGE_TAG)' "$VALUES_FILE"

    git add "$VALUES_FILE"
    if git diff --cached --quiet; then
      echo "No changes to commit"
      exit 0
    fi
    git commit -m "lti prod deploy ${IMAGE_TAG}"
    git push origin "$GITOPS_BRANCH"
