#!/usr/bin/perl

use strict;
use warnings;
use File::HomeDir;
use File::Spec;

# Function to prompt user for input with a default value
sub prompt_with_default {
    my ($message, $default) = @_;
    print "$message [$default]: ";
    my $input = <STDIN>;
    chomp $input;
    return $input || $default;
}

# --- Main Script ---

my $ssh_dir = File::Spec->catfile(File::HomeDir->my_home, '.ssh');
my $config_file = File::Spec->catfile($ssh_dir, 'config');

# Create .ssh directory if it doesn't exist
unless (-d $ssh_dir) {
    mkdir $ssh_dir, 0700 or die "Could not create directory $ssh_dir: $!";
    print "Created directory: $ssh_dir\n";
}

print "--- SSH Config Generator ---\n";
print "This script will help you create or update your SSH config file ($config_file)\n\n";

# --- Scan for available private keys ---
opendir(my $dir, $ssh_dir) or die "Cannot open $ssh_dir: $!";
my @private_keys = grep {
    /^id_[^\.]+$/ && -f File::Spec->catfile($ssh_dir, $_)
} readdir($dir);
closedir($dir);

print "Available private SSH keys in $ssh_dir:\n";
foreach my $key (@private_keys) {
    print "  - $key\n";
}
print "\n";

my @hosts;
my $add_more_hosts = 1;

while ($add_more_hosts) {
    my %host_config;

    print "\nEnter details for the new host:\n";

    print "Host (a short nickname for the server): ";
    chomp($host_config{Host} = <STDIN>);
    die "Host nickname cannot be empty." unless $host_config{Host};

    print "HostName (the actual IP address or domain name): ";
    chomp($host_config{HostName} = <STDIN>);
    die "HostName cannot be empty." unless $host_config{HostName};

    $host_config{User} = prompt_with_default("User (the username to log in with)", $ENV{USER});
    $host_config{Port} = prompt_with_default("Port (the SSH port of the remote server)", "22");

    # Use Ed25519 as default identity file, or suggest from existing ones
    my $default_identity = File::Spec->catfile($ssh_dir, "id_ed25519");
    $host_config{IdentityFile} = prompt_with_default(
        "IdentityFile (private key path, e.g. id_ed25519 or id_rsa)", 
        $default_identity
    );

    unless (-e $host_config{IdentityFile}) {
        warn "⚠️  Warning: Identity file '$host_config{IdentityFile}' does not exist.\n";
    }

    push @hosts, \%host_config;

    print "\nDo you want to add another host? (y/n) [n]: ";
    my $another = <STDIN>;
    chomp $another;
    $add_more_hosts = ($another =~ /^[yY]/);
}

# --- Generate the SSH config content ---
my $config_content = "";
foreach my $host (@hosts) {
    $config_content .= "Host $host->{Host}\n";
    $config_content .= "    HostName $host->{HostName}\n";
    $config_content .= "    User $host->{User}\n";
    $config_content .= "    Port $host->{Port}\n";
    $config_content .= "    IdentityFile $host->{IdentityFile}\n";
    $config_content .= "    IdentitiesOnly yes\n";
    $config_content .= "    ForwardAgent yes\n";
    $config_content .= "    ServerAliveInterval 60\n";
    $config_content .= "    ServerAliveCountMax 3\n";
    $config_content .= "    StrictHostKeyChecking ask\n";
    $config_content .= "\n";
}

# --- Write to the config file ---
if (-e $config_file) {
    print "\nConfiguration file ($config_file) already exists.\n";
    print "Do you want to (a)ppend, (o)verwrite, or (b)ackup and create new? [a]: ";
    my $action = <STDIN>;
    chomp $action;

    if ($action =~ /^[oO]/) {
        open my $fh, '>', $config_file or die "Could not open $config_file for writing: $!";
        print $fh $config_content;
        close $fh;
        print "✅ Successfully overwrote $config_file.\n";
    } elsif ($action =~ /^[bB]/) {
        my $backup_file = "$config_file.bak";
        rename $config_file, $backup_file or die "Could not back up $config_file: $!";
        open my $fh, '>', $config_file or die "Could not open $config_file for writing: $!";
        print $fh $config_content;
        close $fh;
        print "✅ Backed up existing config to $backup_file and created a new one.\n";
    } else {
        open my $fh, '>>', $config_file or die "Could not open $config_file for appending: $!";
        print $fh "\n" . $config_content;
        close $fh;
        print "✅ Successfully appended to $config_file.\n";
    }
} else {
    open my $fh, '>', $config_file or die "Could not open $config_file for writing: $!";
    print $fh $config_content;
    close $fh;
    print "✅ Successfully created $config_file.\n";
}

# Set secure file permissions
chmod 0600, $config_file;

print "\n🎉 SSH configuration generation complete.\n";
