#!/bin/bash

# Build script for systemd-gpio C++ implementation with OpenSSF Security Hardening

set -e

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

echo -e "${GREEN}Building systemd-gpio C++ implementation with OpenSSF security hardening...${NC}"

# Check if cmake is available
if ! command -v cmake &> /dev/null; then
    echo -e "${RED}Error: cmake is not installed. Please install cmake >= 3.20${NC}"
    exit 1
fi

# Check if g++ is available
if ! command -v g++ &> /dev/null; then
    echo -e "${RED}Error: g++ is not installed. Please install g++ >= 9${NC}"
    exit 1
fi

# Create build directory
BUILD_DIR="build"
if [ -d "$BUILD_DIR" ]; then
    echo -e "${YELLOW}Removing existing build directory...${NC}"
    rm -rf "$BUILD_DIR"
fi

mkdir "$BUILD_DIR"
cd "$BUILD_DIR"

# Parse command line arguments
SECURITY_HARDENING=ON
BUILD_TYPE=Release
ENABLE_SANITIZERS=OFF
BUILD_TESTING=OFF
DO_INSTALL=false
DO_PACKAGE=false
DO_TEST=false

show_usage() {
    echo "Usage: $0 [OPTIONS] [install|package|test]"
    echo ""
    echo "Options:"
    echo "  --no-security    Disable OpenSSF security hardening"
    echo "  --debug          Build in debug mode with sanitizers"
    echo "  --sanitizers     Enable sanitizers (debug builds only)"
    echo "  --with-tests     Enable building tests"
    echo "  install          Install after building"
    echo "  package          Build .deb package with dpkg-buildpackage"
    echo "  test             Run tests after building"
    echo "  --help           Show this help message"
    echo ""
    echo "Examples:"
    echo "  $0                    # Build with security hardening"
    echo "  $0 install            # Build and install"
    echo "  $0 test               # Build and run tests"
    echo "  $0 package            # Build .deb package"
    echo "  $0 --debug test       # Debug build with sanitizers and run tests"
    echo "  $0 --no-security      # Build without security hardening"
}

while [[ $# -gt 0 ]]; do
    case $1 in
        --no-security)
            SECURITY_HARDENING=OFF
            shift
            ;;
        --debug)
            BUILD_TYPE=Debug
            ENABLE_SANITIZERS=ON
            shift
            ;;
        --sanitizers)
            ENABLE_SANITIZERS=ON
            shift
            ;;
        --with-tests)
            BUILD_TESTING=ON
            shift
            ;;
        install)
            DO_INSTALL=true
            shift
            ;;
        package)
            DO_PACKAGE=true
            shift
            ;;
        test)
            DO_TEST=true
            shift
            ;;
        --help)
            show_usage
            exit 0
            ;;
        *)
            echo -e "${YELLOW}Unknown option: $1${NC}"
            show_usage
            exit 1
            ;;
    esac
done

# If packaging was requested, run dpkg-buildpackage and exit
if [ "$DO_PACKAGE" == "true" ]; then
    echo -e "${GREEN}Building .deb package with dpkg-buildpackage...${NC}"
    cd ..

    # Generate debian/changelog from git history
    echo -e "${BLUE}Generating debian/changelog from git tags...${NC}"
    ./scripts/generate-changelog.sh

    dpkg-buildpackage -us -uc -b
    echo -e "${GREEN}.deb package(s) created in parent directory${NC}"
    ls -la ../*.deb 2>/dev/null || echo -e "${YELLOW}No .deb files found${NC}"
    exit 0
fi

# Configure with CMake
echo -e "${GREEN}Configuring with CMake...${NC}"
echo -e "${BLUE}  Build Type: ${BUILD_TYPE}${NC}"
echo -e "${BLUE}  Security Hardening: ${SECURITY_HARDENING}${NC}"
echo -e "${BLUE}  Testing: ${BUILD_TESTING}${NC}"
if [ "$BUILD_TYPE" == "Debug" ] && [ "$ENABLE_SANITIZERS" == "ON" ]; then
    echo -e "${BLUE}  Sanitizers: Enabled (Debug mode)${NC}"
fi

cmake .. \
    -DCMAKE_BUILD_TYPE=$BUILD_TYPE \
    -DENABLE_SECURITY_HARDENING=$SECURITY_HARDENING \
    -DBUILD_TESTING=$BUILD_TESTING

# Build
echo -e "${GREEN}Building...${NC}"
# Use nproc on Linux, sysctl on macOS
if command -v nproc >/dev/null 2>&1; then
    CORES=$(nproc)
elif command -v sysctl >/dev/null 2>&1; then
    CORES=$(sysctl -n hw.ncpu)
else
    CORES=4
fi
make -j$CORES

# Check if we should run tests
if [ "$DO_TEST" == "true" ]; then
    echo -e "${GREEN}Running tests...${NC}"
    if [ "$BUILD_TESTING" == "ON" ]; then
        ctest --output-on-failure --verbose
        TEST_RESULT=$?
        if [ $TEST_RESULT -eq 0 ]; then
            echo -e "${GREEN}✓ All tests passed!${NC}"
        else
            echo -e "${RED}✗ Some tests failed (exit code: $TEST_RESULT)${NC}"
            exit $TEST_RESULT
        fi
    else
        echo -e "${YELLOW}Tests were disabled during build configuration${NC}"
    fi
fi

# Check if we should install
if [ "$DO_INSTALL" == "true" ]; then
    echo -e "${GREEN}Installing...${NC}"
    sudo make install
    
    # Reload systemd to pick up the new service file
    echo -e "${GREEN}Reloading systemd...${NC}"
    sudo systemctl daemon-reload
    
    echo -e "${GREEN}Installation complete!${NC}"
    echo -e "${YELLOW}To configure a GPIO pin, create a file /etc/gpio/N (where N is the pin number)${NC}"
    echo -e "${YELLOW}Then enable the service: sudo systemctl enable --now gpio@N.service${NC}"
fi

# Show summary if no specific action was requested
if [ "$DO_INSTALL" == "false" ] && [ "$DO_PACKAGE" == "false" ] && [ "$DO_TEST" == "false" ]; then
    echo -e "${GREEN}Build complete! Binary is in build/systemd-gpio${NC}"
    echo -e "${YELLOW}Available actions:${NC}"
    echo -e "${YELLOW}  ./build.sh install    # Install system-wide${NC}"
    echo -e "${YELLOW}  ./build.sh test       # Run tests${NC}"
    echo -e "${YELLOW}  ./build.sh package    # Build .deb package${NC}"
    if [ "$SECURITY_HARDENING" == "ON" ]; then
        echo -e "${BLUE}Security features: Stack protection, FORTIFY_SOURCE, PIE, RELRO, CFI${NC}"
    fi
fi
