use alienfile;
use Config;
use Path::Tiny qw(path);

# Only use PkgConfig on non-Windows systems
if ($^O ne 'MSWin32') {
    plugin PkgConfig => (
        pkg_name => 'libduckdb',
    );
}

# Add hook to ensure system installation properties are properly set
meta->around_hook(
    gather_system => sub {
        my ($orig, $build) = @_;
        $orig->($build);
        
        # Ensure properties are set for system installs
        unless(defined $build->runtime_prop->{version}) {
            $build->runtime_prop->{version} = '1.2.2';
            if ($^O ne 'MSWin32') {
                my $version = `pkg-config --modversion libduckdb 2>/dev/null`;
                if ($version && $? == 0) {
                    chomp $version;
                    $build->runtime_prop->{version} = $version;
                }
            }
        }
        
        unless(defined $build->runtime_prop->{cflags}) {
            $build->runtime_prop->{cflags} = '-I/usr/include';
            if ($^O ne 'MSWin32') {
                my $cflags = `pkg-config --cflags libduckdb 2>/dev/null`;
                if ($cflags && $? == 0) {
                    chomp $cflags;
                    $build->runtime_prop->{cflags} = $cflags;
                }
            }
        }
        
        unless(defined $build->runtime_prop->{libs}) {
            $build->runtime_prop->{libs} = '-L/usr/lib -lduckdb';
            if ($^O ne 'MSWin32') {
                my $libs = `pkg-config --libs libduckdb 2>/dev/null`;
                if ($libs && $? == 0) {
                    chomp $libs;
                    $build->runtime_prop->{libs} = $libs;
                }
            }
        }
    }
);

# Configure for share (i.e., when building from source or downloading prebuilt binaries)
share {
    # Current DuckDB version to use
    my $duckdb_version = '1.2.2';
    
    # Determine platform and architecture
    my $os = $^O;
    my $arch = '';  # Initialize with empty string to avoid uninitialized warnings
    my $binary_suffix;
    my $download_url;
    
    # Set platform-specific values
    if ($os eq 'linux') {
        # Linux - detect architecture
        if ($Config{archname} =~ /x86_64|amd64/i) {
            $arch = 'amd64';
        } elsif ($Config{archname} =~ /arm64|aarch64/i) {
            $arch = 'arm64';
        } elsif ($Config{archname} =~ /i[3456]86/i) {
            $arch = 'i386';
        } else {
            # If cannot determine, default to x86_64
            $arch = 'amd64';
            log "Unknown Linux architecture, defaulting to amd64";
        }
        $binary_suffix = 'so';
        $download_url = "https://github.com/duckdb/duckdb/releases/download/v$duckdb_version/libduckdb-linux-$arch.zip";
    } 
    elsif ($os eq 'darwin') {
        # macOS - use universal binary
        $arch = 'universal';  # Define the architecture for macOS
        $download_url = "https://github.com/duckdb/duckdb/releases/download/v$duckdb_version/libduckdb-osx-universal.zip";
        $binary_suffix = 'dylib';
    } 
    elsif ($os eq 'MSWin32') {
        # Windows - 32 or 64 bit
        my $is_64bit = $Config{ptrsize} == 8;
        $arch = $is_64bit ? 'amd64' : 'i386';
        $download_url = "https://github.com/duckdb/duckdb/releases/download/v$duckdb_version/libduckdb-windows-$arch.zip";
        $binary_suffix = 'dll';
    }
    else {
        # Other OS
        $binary_suffix = 'so';  # Default
        $arch = 'unknown';
    }
    
    log "Detected platform: $os, architecture: $arch";
    log "Will try binary download from: $download_url";
    
    # Always try downloading prebuilt binary first
    plugin 'Download' => (
        url => $download_url,
        version => $duckdb_version,
    );
    
    # Extract the zip file
    plugin 'Extract' => 'zip';
    
    # Set up build and installation steps for binary
    build [
        # Create directories
        [ 'mkdir', '-p', '%{.install.prefix}/include' ],
        [ 'mkdir', '-p', '%{.install.prefix}/lib' ],
    ];
    
    # Handle file organization after extraction
    after 'build' => sub {
        my ($build) = @_;
        my $extract_dir = $build->install_prop->{extract};
        
        log "Organizing files from $extract_dir";
        
        # Make standard directories
        my $prefix = $build->install_prop->{prefix};
        my $include_dir = path("$prefix/include");
        my $lib_dir = path("$prefix/lib");
        $include_dir->mkpath;
        $lib_dir->mkpath;
        
        # Copy files to the appropriate locations
        my $header_count = 0;
        my $lib_count = 0;
        foreach my $file (path($extract_dir)->children) {
            my $basename = $file->basename;
            # Copy header files to include/ directory
            if ($basename =~ /\.(h|hpp)$/) {
                path($file)->copy("$include_dir/$basename");
                $header_count++;
            }
            # Copy library files to lib/ directory
            elsif ($basename =~ /\.(?:$binary_suffix|a|lib)$/i) {
                path($file)->copy("$lib_dir/$basename");
                $lib_count++;
            }
        }
        
        log "Copied $header_count header files and $lib_count library files to standard locations";
        
        # If we're on Windows, create a dummy pkg-config file to satisfy the PkgConfig plugin
        if ($^O eq 'MSWin32') {
            my $pkgconfig_dir = path("$prefix/lib/pkgconfig");
            $pkgconfig_dir->mkpath;
            
            my $pc_file = path("$pkgconfig_dir/libduckdb.pc");
            my $pc_content = <<EOT;
prefix=$prefix
exec_prefix=\${prefix}
libdir=\${prefix}/lib
includedir=\${prefix}/include

Name: libduckdb
Description: DuckDB database library
Version: $duckdb_version
Cflags: -I\${includedir}
Libs: -L\${libdir} -lduckdb
EOT
            
            $pc_file->spew($pc_content);
            log "Created pkg-config file: $pc_file";
        }
    };
    
    # Windows-specific hook to ensure properties are set correctly
    if ($^O eq 'MSWin32') {
        meta->around_hook(
            gather_share => sub {
                my ($orig, $build) = @_;
                
                # Skip the original gather_share if it's likely to fail on Windows
                eval { $orig->($build) };
                if ($@) {
                    log "Original gather_share hook failed, using direct property setting";
                }
                
                # Get the installation directory
                my $prefix = $build->install_prop->{prefix};
                log "Setting runtime properties for installation in $prefix";
                
                # Set properties directly without using pkg-config
                $build->runtime_prop->{version} = $duckdb_version;
                $build->runtime_prop->{cflags} = "-I$prefix/include";
                $build->runtime_prop->{libs} = "-L$prefix/lib -lduckdb";
                
                # Debug output
                log "VERSION: " . $build->runtime_prop->{version};
                log "CFLAGS: " . $build->runtime_prop->{cflags};
                log "LIBS: " . $build->runtime_prop->{libs};
                
                # Check if files exist where expected
                log "Header exists: " . (-e "$prefix/include/duckdb.h" ? "YES" : "NO");
                my @libs = glob("$prefix/lib/*duck*");
                log "Libraries: " . join(", ", @libs);
            },
        );
    }
    else {
        # Standard hook for other platforms
        meta->around_hook(
            gather_share => sub {
                my ($orig, $build) = @_;
                $orig->($build);
                
                # Get the installation directory
                my $prefix = $build->install_prop->{prefix};
                log "Setting runtime properties for installation in $prefix";
                
                # Set properties directly
                $build->runtime_prop->{version} = $duckdb_version;
                $build->runtime_prop->{cflags} = "-I$prefix/include";
                $build->runtime_prop->{libs} = "-L$prefix/lib -lduckdb";
                
                # Debug output
                log "VERSION: " . $build->runtime_prop->{version};
                log "CFLAGS: " . $build->runtime_prop->{cflags};
                log "LIBS: " . $build->runtime_prop->{libs};
                
                # Check if files exist where expected
                log "Header exists: " . (-e "$prefix/include/duckdb.h" ? "YES" : "NO");
                my @libs = glob("$prefix/lib/*duck*");
                log "Libraries: " . join(", ", @libs);
            },
        );
    }
};