pipeline {
    agent any
    stages {
        stage('Tests and compiling binaries') {
            when {
                expression { env.CHANGE_BRANCH?.startsWith('feature/') || env.CHANGE_BRANCH?.startsWith('rc') }
            }
            steps {
                script {
                    echo "Building and running tests in Docker for feature branch..."
                    try {
                        def targetDirAmd = "${env.WORKSPACE}/${env.CHANGE_BRANCH}/amd64"
                        def targetDirRisc = "${env.WORKSPACE}/${env.CHANGE_BRANCH}/riscv64"
                        
                        sh "mkdir -p ${targetDirAmd}"
                        sh "mkdir -p ${targetDirRisc}"
                        
                        sh """
                        docker build --network=host -t e-monitor .
                        docker run --name e-monitor --dns 8.8.8.8 --network=host e-monitor:latest
                        """
                        
                        sh "cp noxis-rs/settings.json ${targetDirAmd}"
                        sh "cp noxis-rs/settings.json ${targetDirRisc}"

                        sh "docker cp e-monitor:/usr/src/kii/target/x86_64-unknown-linux-gnu/release/noxis-cli ${targetDirAmd}"
                        sh "docker cp e-monitor:/usr/src/kii/target/x86_64-unknown-linux-gnu/release/noxis-rs ${targetDirAmd}"

                        sh "docker cp e-monitor:/usr/src/kii/target/riscv64gc-unknown-linux-gnu/release/noxis-cli ${targetDirRisc}"
                        sh "docker cp e-monitor:/usr/src/kii/target/riscv64gc-unknown-linux-gnu/release/noxis-rs ${targetDirRisc}"

                        echo "Tests passed successfully and binaries were extracted!"
                    } catch (Exception e) {
                        echo "Tests failed during Docker run."
                        error "Build failed at 'CI for feature' stage."
                    }
                }
            }
        }

        stage('Calculate Install Size') {
            when {
                expression { env.CHANGE_BRANCH?.startsWith('rc') }
            }
            steps {
                script {
                    echo "Calculating installation size for rc branch..."
                    def targetDirAmd = "${env.WORKSPACE}/${env.CHANGE_BRANCH}/amd64"
                    def targetDirRisc = "${env.WORKSPACE}/${env.CHANGE_BRANCH}/riscv64"

                    def installSizeAmd = sh(script: "du -s --block-size=1024 ${targetDirAmd} | awk '{print \$1}'", returnStdout: true).trim()
                    def installSizeRisc = sh(script: "du -s --block-size=1024 ${targetDirRisc} | awk '{print \$1}'", returnStdout: true).trim()
                    
                    env.INSTALL_SIZE_AMD = installSizeAmd
                    env.INSTALL_SIZE_RISC = installSizeRisc

                    echo "Installation size for amd64: ${env.INSTALL_SIZE_AMD} kB"
                    echo "Installation size for riscv64: ${env.INSTALL_SIZE_RISC} kB"
                }
            }
        }

        stage('Create Deb Packages') {
            when {
                expression { env.CHANGE_BRANCH?.startsWith('rc') }
            }
            steps {
                script {
                    echo "Creating deb packages for rc branch..."

                    def targetDirAmd = "${env.WORKSPACE}/${env.CHANGE_BRANCH}/amd64"
                    def targetDirRisc = "${env.WORKSPACE}/${env.CHANGE_BRANCH}/riscv64"
                    def packageName = "noxis"
                    def version = sh(script: "git describe --tags --abbrev=0", returnStdout: true).trim()                    
                    def createDebPackage = { arch, binDir, targetDir, installSize ->
                        echo "Creating deb package for ${arch}..."

                        sh """
                        mkdir -p ${targetDir}/package/DEBIAN
                        mkdir -p ${targetDir}/package/usr/local/enode/${packageName}
                        mkdir -p ${targetDir}/package/usr/bin
                        mkdir -p ${targetDir}/package/etc/enode
                        mkdir -p ${targetDir}/package/lib/systemd/system
                        
                        cp ${binDir}/noxis-cli ${targetDir}/package/usr/local/enode/${packageName}/
                        cp ${binDir}/noxis-rs ${targetDir}/package/usr/local/enode/${packageName}/
                        cp ${binDir}/settings.json ${targetDir}/package/etc/enode/

                        cat > ${targetDir}/package/DEBIAN/control <<EOF
Package: ${packageName}
Version: ${version}
Section: unknown
Priority: optional
Architecture: ${arch}
Maintainer: kis <supervisor@rosatom.ru>
Description: Noxis Agent Linux
Installed-Size: ${installSize}
EOF

                        chmod +x ${targetDir}/package/usr/local/enode/${packageName}/noxis-cli
                        chmod +x ${targetDir}/package/usr/local/enode/${packageName}/noxis-rs

                        cat > ${targetDir}/package/DEBIAN/postinst <<EOF
#!/bin/bash
ln -sf "/usr/local/enode/${packageName}/noxis-cli" "/usr/bin/noxis-cli"
ln -sf "/usr/local/enode/${packageName}/noxis-rs" "/usr/bin/noxis-rs"
systemctl daemon-reload
systemctl start ${packageName}.service
EOF
                        chmod +x ${targetDir}/package/DEBIAN/postinst

                        cat > ${targetDir}/package/lib/systemd/system/${packageName}.service <<EOF
[Unit]
Description=Noxis Service
After=network.target

[Service]
ExecStart=/usr/local/enode/${packageName}/noxis-rs
Restart=always

[Install]
WantedBy=multi-user.target
EOF

                        dpkg-deb --build ${targetDir}/package ${targetDir}/rc/${arch}/${packageName}_${version}_${arch}.deb
                        echo "${packageName}_${version}_${arch}.deb created successfully!"
                        """
                    }

                    createDebPackage("amd64", targetDirAmd, env.WORKSPACE, env.INSTALL_SIZE_AMD)
                    createDebPackage("riscv64", targetDirRisc, env.WORKSPACE, env.INSTALL_SIZE_RISC)

                    env.DEB_PATH_AMD64 = "${env.WORKSPACE}/rc/amd64/${packageName}_${version}_amd64.deb"
                    env.DEB_PATH_RISCV64 = "${env.WORKSPACE}/rc/riscv64/${packageName}_${version}_riscv64.deb"
                }
            }
        }

        stage('Transfer Binaries') {
            when {
                expression { env.CHANGE_BRANCH?.startsWith('feature/') }
            }
            steps {
                script {
                    echo "Transferring binaries packages to remote machine..."
                    
                    withCredentials([usernamePassword(credentialsId: 'ift', passwordVariable: 'SSH_PASS', usernameVariable: 'SSH_USER')]) {
                        def targetDir = "${env.WORKSPACE}/${env.CHANGE_BRANCH}"
                        def remote = [:]
                        remote.name = "remote-server"
                        remote.host = "192.168.2.33"
                        remote.user = SSH_USER
                        remote.password = SSH_PASS
                        remote.allowAnyHosts = true
                        
                        sshPut remote: remote, from: "${targetDir}", into: "/home/user/deployments/"
                        echo "Binaries successfully transferred to remote machine."
                    }
                }
            }
        }

        stage('Upload Debs to Repository') {
            when {
                expression { env.CHANGE_BRANCH?.startsWith('rc') }
            }
            steps {
                script {
                    echo "Uploading deb packages to remote repository..."

                    withCredentials([usernamePassword(credentialsId: 'prod', passwordVariable: 'SSH_PASS', usernameVariable: 'SSH_USER')]) {
                        def remote = [:]
                        remote.name = "remote-server"
                        remote.host = "192.168.2.99"
                        remote.user = SSH_USER
                        remote.password = SSH_PASS
                        remote.allowAnyHosts = true

                        echo "Uploading deb packages using sshPut..."
                        sshPut remote: remote, from: "${env.DEB_PATH_AMD64}", into: "/home/user/repo/debs/"
                        sshPut remote: remote, from: "${env.DEB_PATH_RISCV64}", into: "/home/user/repo/debs/"

                        echo "Running repository update commands via sshCommand..."
                        sshCommand remote: remote, command: '''
                            export DEBIAN_FRONTEND=noninteractive
                            cd /home/user/repo/debs/
                            for deb in *.deb; do
                                reprepro -b /var/www/deb/debian/ includedeb stable $deb
                            done
                            rm -f *.deb
                        '''

                        echo "Deb packages successfully uploaded and added to the repository!"
                    }
                }
            }
        }
    }

    post {
        always {
            script {
                echo "Cleaning up workspace..."
                try {
                    if (fileExists("${env.WORKSPACE}/package/")) {
                        sh "rm -rf ${env.WORKSPACE}/package/"
                    }
                    if (fileExists("${env.WORKSPACE}/rc/")) {
                        sh "rm -rf ${env.WORKSPACE}/rc/"
                    }
                    sh "docker stop e-monitor && docker rm e-monitor"
                } catch (Exception e) {
                    echo "Failed to clean up workspace: ${e}"
                }
            }
        }
        success {
            script {
                when {
                    expression { env.CHANGE_BRANCH?.startsWith('rc') }
                }
                echo "Attempting to merge PR ${env.CHANGE_ID} into master..."
                withCredentials([usernamePassword(credentialsId: 'gitea_creds', usernameVariable: 'GITEA_USER', passwordVariable: 'GITEA_PASS')]) {
                    def prId = env.CHANGE_ID
                    sh """
                    curl -X POST \
                         -u "${GITEA_USER}:${GITEA_PASS}" \
                         -H "Content-Type: application/json" \
                         -d '{"Do":"merge"}' \
                         http://git.entcor/api/v1/repos/VladislavD/runner-rs/pulls/${prId}/merge
                    """
                    echo "PR ${prId} merged successfully into master!"
                }
            }
        }
        failure {
            echo "Pipeline failed. Check the logs for details."
        }
        aborted {
            echo "Pipeline was aborted."
        }
    }
}