// Jenkinsfile for Java Microservices Project

pipeline {
    agent any

    environment {
        // Define the Docker registry to push images to.
        // Replace with your actual Docker registry (e.g., your-docker-hub-username or ECR/GCR registry)
        DOCKER_REGISTRY = 'your-docker-registry'
        // Define the Docker image tag. Using BUILD_NUMBER for unique tags.
        DOCKER_IMAGE_TAG = "${env.BUILD_NUMBER}"
        // SonarQube server configuration (replace 'sonarqube-server' with your SonarQube server name in Jenkins)
        // SONAR_SCANNER_HOME = tool 'SonarScanner' // Assumes SonarScanner is configured as a tool in Jenkins
    }

    stages {
        stage('Unit Tests') {
            steps {
                script {
                    // Run unit tests for each service
                    def services = ['user-service', 'product-service', 'order-service', 'notification-service']
                    for (int i = 0; i < services.size(); i++) {
                        def service = services[i]
                        dir(service) {
                            echo "Running unit tests for ${service}..."
                            sh 'mvn test' // Runs unit tests
                        }
                    }
                }
            }
        }

        stage('SonarQube Analysis') {
            steps {
                script {
                    // Perform SonarQube analysis for each service
                    // The 'withSonarQubeEnv' step injects SonarQube server details (URL, credentials)
                    // Assumes a SonarQube server is configured in Jenkins with the name 'sonarqube-server'
                    withSonarQubeEnv(credentialsId: 'sonarqube-token', scannerHome: 'SONAR_SCANNER_HOME') { // Replace 'sonarqube-token' with your actual SonarQube token credential ID
                        def services = ['user-service', 'product-service', 'order-service', 'notification-service']
                        for (int i = 0; i < services.size(); i++) {
                            def service = services[i]
                            dir(service) {
                                echo "Running SonarQube analysis for ${service}..."
                                // 'catchError' ensures the pipeline continues even if SonarQube quality gate fails
                                // The build will be marked as UNSTABLE in case of quality gate failure.
                                catchError(buildResult: 'UNSTABLE', stageResult: 'UNSTABLE') {
                                    sh "mvn sonar:sonar -Dsonar.projectKey=${service} -Dsonar.projectName=${service}"
                                }
                            }
                        }
                    }
                }
            }
        }

        stage('Package and Docker Build') {
            steps {
                script {
                    // Build and package each Spring Boot application and then build its Docker image
                    def services = ['user-service', 'product-service', 'order-service', 'notification-service']
                    for (int i = 0; i < services.size(); i++) {
                        def service = services[i]
                        dir(service) {
                            echo "Packaging ${service}..."
                            sh 'mvn clean package -DskipTests' // Package into JAR, skip tests as they ran in previous stage

                            echo "Building Docker image for ${service}..."
                            // The image will be tagged with the service name and build number.
                            sh "docker build -t ${DOCKER_REGISTRY}/${service}:${DOCKER_IMAGE_TAG} ."
                            // Optional: Push the Docker image to the registry
                            // sh "docker push ${DOCKER_REGISTRY}/${service}:${DOCKER_IMAGE_TAG}"
                        }
                    }
                }
            }
        }

        stage('Deploy to Kubernetes') {
            steps {
                script {
                    // This stage assumes you have kubectl configured and connected to a Kubernetes cluster.
                    // It will apply the Kubernetes manifests for each service.
                    echo "Deploying Java microservices to Kubernetes..."

                    def services = ['user-service', 'product-service', 'order-service', 'notification-service']
                    for (int i = 0; i < services.size(); i++) {
                        def service = services[i]
                        echo "Applying ${service} Kubernetes manifests..."
                        sh "kubectl apply -f ${service}/kubernetes/deployment.yaml"
                        sh "kubectl apply -f ${service}/kubernetes/service.yaml"
                    }
                    echo "Deployment to Kubernetes complete."
                }
            }
        }
    }

    post {
        always {
            echo "Pipeline finished."
        }
        failure {
            echo "Pipeline failed. Check logs for errors."
        }
        unstable {
            echo "Pipeline finished with UNSTABLE status (e.g., SonarQube quality gate failed)."
        }
        success {
            echo "Pipeline finished successfully."
        }
    }
}
