#!/bin/bash

# apt-ostree Debian Package Builder
# Enhanced version for CI/CD environments with better error handling

set -euo pipefail

# Colors for output
GREEN='\033[0;32m'
BLUE='\033[0;34m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
NC='\033[0m'

print_status() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

print_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

print_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

print_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

print_header() {
    echo ""
    echo -e "${BLUE}================================${NC}"
    echo -e "${BLUE}$1${NC}"
    echo -e "${BLUE}================================${NC}"
}

# Function to check if a command exists
command_exists() {
    command -v "$1" >/dev/null 2>&1
}

# Function to validate dependencies
validate_dependencies() {
    local missing_deps=()
    
    for dep in "$@"; do
        if ! command_exists "$dep"; then
            missing_deps+=("$dep")
        fi
    done
    
    if [ ${#missing_deps[@]} -gt 0 ]; then
        print_error "Missing required dependencies: ${missing_deps[*]}"
        print_status "Please install the missing packages and try again."
        exit 1
    fi
}

# Function to get version from Cargo.toml
get_version_from_cargo() {
    if [ -f "Cargo.toml" ]; then
        grep '^version = ' Cargo.toml | sed 's/version = "\(.*\)"/\1/' | tr -d ' '
    else
        echo "unknown"
    fi
}

# Function to get project name from Cargo.toml
get_project_name_from_cargo() {
    if [ -f "Cargo.toml" ]; then
        grep '^name = ' Cargo.toml | sed 's/name = "\(.*\)"/\1/' | tr -d ' '
    else
        echo "unknown"
    fi
}

# Function to check build environment
check_build_environment() {
    print_status "Checking build environment..."
    
    # Check if we're in the right directory
    if [ ! -f "Cargo.toml" ]; then
        print_error "Cargo.toml not found. Please run this script from the project root."
        exit 1
    fi
    
    # Check if debian directory exists
    if [ ! -d "debian" ]; then
        print_error "debian/ directory not found. Please ensure Debian packaging files are present."
        exit 1
    fi
    
    # Validate required dependencies
    validate_dependencies dpkg-buildpackage dpkg-architecture
    
    # Check Rust environment
    if command_exists cargo; then
        print_status "Rust environment found:"
        cargo --version
        rustc --version
    else
        print_error "Cargo not found. Please ensure Rust is installed."
        print_status "You can install Rust using: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh"
        exit 1
    fi
    
    # Check if we're on a Debian-based system
    if [ ! -f "/etc/debian_version" ]; then
        print_warning "This doesn't appear to be a Debian-based system."
        print_warning "Some features may not work correctly."
    fi
}

# Function to clean previous builds
clean_previous_builds() {
    print_status "Cleaning previous build artifacts..."
    
    # Remove previous .deb files
    find . -maxdepth 1 -name "*.deb" -delete 2>/dev/null || true
    find . -maxdepth 1 -name "*.dsc" -delete 2>/dev/null || true
    find . -maxdepth 1 -name "*.tar.*" -delete 2>/dev/null || true
    find . -maxdepth 1 -name "*.buildinfo" -delete 2>/dev/null || true
    find . -maxdepth 1 -name "*.changes" -delete 2>/dev/null || true
    
    # Clean debian build directory
    if [ -d "debian/cargo" ]; then
        rm -rf debian/cargo
    fi
}

# Function to build the package
build_package() {
    local build_opts=()
    
    print_status "Building apt-ostree package..."
    
    # Add build options
    build_opts+=(-us -uc -b)  # No signing, no source package, binary only
    
    # Check if we want to build source package too
    if [ "${BUILD_SOURCE:-false}" = "true" ]; then
        build_opts=(-us -uc)  # No signing, no source package
    fi
    
    # Check if we want to sign the package
    if [ "${SIGN_PACKAGE:-false}" = "true" ] && command_exists gpg; then
        build_opts=(-sa -k"${GPG_KEY:-}" -b)  # Sign with specified key
    fi
    
    print_status "Running dpkg-buildpackage with options: ${build_opts[*]}"
    dpkg-buildpackage "${build_opts[@]}"
}

# Function to verify build results
verify_build_results() {
    print_status "Verifying build results..."
    
    local deb_files=()
    local dsc_files=()
    local changes_files=()
    
    # Find built packages
    while IFS= read -r -d '' file; do
        deb_files+=("$file")
    done < <(find . -maxdepth 1 -name "*.deb" -print0 2>/dev/null)
    
    while IFS= read -r -d '' file; do
        dsc_files+=("$file")
    done < <(find . -maxdepth 1 -name "*.dsc" -print0 2>/dev/null)
    
    while IFS= read -r -d '' file; do
        changes_files+=("$file")
    done < <(find . -maxdepth 1 -name "*.changes" -print0 2>/dev/null)
    
    if [ ${#deb_files[@]} -gt 0 ]; then
        print_success "Built packages:"
        for file in "${deb_files[@]}"; do
            echo "  - $(basename "$file")"
        done
    else
        print_error "No .deb files found!"
        exit 1
    fi
    
    if [ ${#dsc_files[@]} -gt 0 ]; then
        print_status "Source package:"
        for file in "${dsc_files[@]}"; do
            echo "  - $(basename "$file")"
        done
    fi
    
    if [ ${#changes_files[@]} -gt 0 ]; then
        print_status "Changes file:"
        for file in "${changes_files[@]}"; do
            echo "  - $(basename "$file")"
        done
    fi
}

# Main execution
main() {
    # Configuration
    PROJECT_NAME=$(get_project_name_from_cargo)
    VERSION=$(get_version_from_cargo)
    
    print_header "apt-ostree Debian Package Builder"
    print_status "Project: $PROJECT_NAME"
    print_status "Version: $VERSION"
    print_status "Build time: $(date)"
    
    # Check build environment
    check_build_environment
    
    # Clean previous builds
    clean_previous_builds
    
    # Build the package
    if build_package; then
        print_success "Package built successfully!"
        verify_build_results
    else
        print_error "Package build failed!"
        exit 1
    fi
    
    print_success "Build completed successfully!"
}

# Handle command line arguments
while [[ $# -gt 0 ]]; do
    case $1 in
        --build-source)
            BUILD_SOURCE=true
            shift
            ;;
        --sign-package)
            SIGN_PACKAGE=true
            shift
            ;;
        --gpg-key)
            GPG_KEY="$2"
            shift 2
            ;;
        --help)
            echo "Usage: $0 [OPTIONS]"
            echo "Options:"
            echo "  --build-source     Build source package in addition to binary"
            echo "  --sign-package     Sign the package with GPG"
            echo "  --gpg-key KEY      GPG key to use for signing"
            echo "  --help             Show this help message"
            exit 0
            ;;
        *)
            print_error "Unknown option: $1"
            print_status "Use --help for usage information"
            exit 1
            ;;
    esac
done

# Run main function
main "$@" 