pipeline {
  agent any
  environment {
    MAVEN_CACHE = "${env.WORKSPACE}/.m2"
    NPM_CACHE = "${env.WORKSPACE}/.npm-cache"
    SONAR_TOKEN = credentials('sonar-token')
  }
  options {
    timestamps()
    skipStagesAfterUnstable()
  }
  stages {
    stage('Checkout') {
      steps {
        checkout scm
      }
    }
    stage('Backend: Build & Test') {
      agent {
        docker {
          image 'maven:3.9.9-eclipse-temurin-21'
          args "-v ${env.WORKSPACE}/.m2:/root/.m2"
        }
      }
      environment {
        MAVEN_OPTS = '-Dmaven.repo.local=/root/.m2/repository'
      }
      steps {
        dir('backend') {
          sh './mvnw --version'
          sh './mvnw clean test -Dmaven.repo.local=/root/.m2/repository'
          sh './mvnw package -DskipTests -Dmaven.repo.local=/root/.m2/repository'
        }
      }
      post {
        always {
          junit 'backend/target/surefire-reports/*.xml'
        }
      }
    }
    stage('Backend: SonarQube Analysis') {
      agent {
        docker {
          image 'maven:3.9.9-eclipse-temurin-21'
          args "-v ${env.WORKSPACE}/.m2:/root/.m2"
        }
      }
      steps {
        withSonarQubeEnv('SonarQube') {
          dir('backend') {
            sh './mvnw sonar:sonar -Dsonar.projectKey=code-journey-backend -Dsonar.host.url=${SONAR_HOST_URL} -Dsonar.login=${SONAR_TOKEN} -Dmaven.repo.local=/root/.m2/repository'
          }
        }
      }
    }
    stage('Frontend: Install & Build') {
      agent {
        docker {
          image 'node:20-alpine'
          args "-v ${env.WORKSPACE}/.npm-cache:/root/.npm -u root"
        }
      }
      steps {
        dir('frontend') {
          sh 'npm ci --cache /root/.npm --prefer-offline'
          sh 'npm run build'
        }
      }
    }
    stage('Frontend: SonarQube Analysis') {
      agent {
        docker {
          image 'node:20-alpine'
          args "-v ${env.WORKSPACE}/.npm-cache:/root/.npm -u root"
        }
      }
      steps {
        withSonarQubeEnv('SonarQube') {
          dir('frontend') {
            sh 'npm install -g sonar-scanner'
            sh 'sonar-scanner -Dsonar.projectKey=code-journey-frontend -Dsonar.sources=src -Dsonar.host.url=${SONAR_HOST_URL} -Dsonar.login=${SONAR_TOKEN}'
          }
        }
      }
    }
    stage('Docker: Build Images') {
      when {
        anyOf {
          branch 'main'
          branch 'develop'
        }
      }
      agent {
        docker {
          image 'docker:24.0.5-dind'
          args '--privileged -v /var/run/docker.sock:/var/run/docker.sock'
        }
      }
      steps {
        sh 'docker build -t code-journey-backend:latest backend'
        sh 'docker build -t code-journey-frontend:latest frontend'
      }
    }
  }
  post {
    always {
      archiveArtifacts artifacts: 'backend/target/*.jar,frontend/.next/**', allowEmptyArchive: true
    }
  }
}
