#!/usr/bin/perl

# Name: ALT Mirror Switcher
# Autor: Aleksandr Shamaraev <shad@altlinux.org>
# License: GPLv2+
# URL: https://altlinux.space/shad

# Inspired by the apt-repo package and uses a small part of its code.

use strict;
use warnings;
use Config::Tiny;
use String::Util 'trim';
use Date::Calc qw(check_date);

my $version = '1.0.0';

my $dir;
my $cmd = '';
my $cmd2 = '';
my $cli_mirror = '';
my $active_mirror = '';
my @enabled_list = ();
my $conf_list = '/etc/apt/sources.list.d/*.list';
my $ams_path = "/etc/apt/sources.list.d/ams.list";
my $conf_path = "/usr/share/alt-mirror-switcher/";
my $exclude_list = "/etc/apt/sources.list.d/altsp.list";
my $archive_link = "rpm [alt] https://ftp.altlinux.org/pub/distributions/archive/sisyphus/date/";
my @archive_end = (" x86_64 classic", " x86_64-i586 classic", " noarch classic");

$dir = $conf_list;
$dir =~ s/\*\.list$//;

$cmd = $ARGV[0] if scalar @ARGV > 0;
$cmd2 = $ARGV[1] if scalar @ARGV > 0;

my $disabled_sources_flag = 0;

if ( $cmd =~ /-(N|C|CN|NC)$/ ) {$disabled_sources_flag = 1;} else {$disabled_sources_flag = 0;}

# disabled source.list
sub disabled_sources{
    opendir( DIR, "/etc/apt/" );
    rename '/etc/apt/sources.list', '/etc/apt/sources.list.tmp' or die "Cannot switch mirror: $!";
    open(my $fl, "<", '/etc/apt/sources.list.tmp');
    open DISABLED_SOURCES, '>', '/etc/apt/sources.list' or die "Can't create /etc/apt/sources.list: $!";
    while (my $line = <$fl>) {
        my $t2 = substr($line, 0, 3);
        if ($t2 eq'rpm') {
            print DISABLED_SOURCES "#$line";
        }
        else {
            print DISABLED_SOURCES $line;
        }
    }
    close($fl);
    close DISABLED_SOURCES;
    unlink( '/etc/apt/sources.list.tmp' ) if -e '/etc/apt/sources.list.tmp';
    closedir( DIR );
}

# identifying all active mirrors

opendir( DIR, $dir );
foreach my $name (sort readdir( DIR )) {
    if( $name =~ /\.list$/)
    {
        if ((trim($dir . $name) ne trim($ams_path)) && (trim($dir . $name) ne trim($exclude_list)))
        {
            open(my $fl, "<", $dir . $name);
            while (my $line = <$fl>) {
                if (($line =~ /\[p1/) or ($line =~ /\[alt\]/)) {
                    my $t2 = substr($line, 0, 3);
                    if ($t2 eq'rpm') {
                        push @enabled_list, $dir . $name;
                        last;
                    }
                }
            }
            close($fl);
        }
    }
}
closedir( DIR );

my $num = @enabled_list;

# automatic restore active list if GUI ams and conf exist
if (( -e $conf_path . 'ams.conf') && ( -e $conf_path . 'alt-mirror-switcher.py'))
{
 if ($cmd =~ /-(ND|DN|D|CD|DC|NDC|DNC|NCD|CND|DCN|CDN)$/ ) { $disabled_sources_flag = 1; }
 else
  {
    my $config = Config::Tiny->read($conf_path . 'ams.conf');
    my $activ = $config->{mirror}->{activ};
    my $file = $config->{mirror}->{file};
    my $protocol= $config->{mirror}->{protocol};
    my $flag_check = 1;

    # Checking if a mirror is active from the configuration file
    open(my $fl, "<", $file);
    while (my $line = <$fl>) {
        if (($line =~ /\[p1/) or ($line =~ /\[alt\]/)) {
            my $t2 = substr($line, 0, 3);
            if ($t2 eq'rpm') {
                $flag_check = 0;
                last;
            }
        }
    }
    close($fl);

    if ($flag_check == 1)
    {
        # disabling all mirrors
        if ($num>0)
        {
            opendir( DIR, $dir );
            foreach my $name (@enabled_list) {
                rename $name, $name . '.tmp' or die "Cannot disabling mirror: $!";
                open($fl, "<", $name . '.tmp');
                open NAME_MIRROR, '>', $name or die "Can't create $name: $!";
                while (my $line = <$fl>) {
                    my $t2 = substr($line, 0, 3);
                    if ($t2 eq'rpm') {
                        print NAME_MIRROR "#$line";
                    }
                    else {
                        print NAME_MIRROR $line;
                    }
                }
                close($fl);
                close NAME_MIRROR;
                unlink( $name . '.tmp' ) if -e $name . '.tmp';
            }
            closedir( DIR );
        }

        # enabling a mirror from a configuration file
        opendir( DIR, $dir );
        rename $file, $file . '.tmp' or die "Cannot switch mirror: $!";
        open($fl, "<", $file . '.tmp');
        open NEW_MIRROR, '>', $file or die "Can't create $file: $!";
        while (my $line = <$fl>) {
            if ($line =~ $protocol){
                print NEW_MIRROR substr($line, 1);
            }
            else {
                print NEW_MIRROR $line;
            }
        }
        close($fl);
        close NEW_MIRROR;
        unlink( $file . '.tmp' ) if -e $file . '.tmp';
        closedir( DIR );

        print("Restored mirror from GUI utility config file.\n");

        if ($disabled_sources_flag eq 0){
            print "Disabled: /etc/apt/sources.list\n";
            disabled_sources();
        }

    }
  }
}
#-------

# enabled source.list
sub sourceson{
    opendir( DIR, "/etc/apt/" );
    rename '/etc/apt/sources.list', '/etc/apt/sources.list.tmp' or die "Cannot switch mirror: $!";
    open(my $fl, "<", '/etc/apt/sources.list.tmp');
    open ENABLED_SOURCES, '>', '/etc/apt/sources.list' or die "Can't create /etc/apt/sources.list: $!";
    while (my $line = <$fl>) {
        my $t2 = trim(substr($line, 1, 4));
        if (trim($t2) eq 'rpm') {
            print ENABLED_SOURCES substr($line, 1);
        }
        else {
            print ENABLED_SOURCES $line;
        }
    }
    close($fl);
    close ENABLED_SOURCES;
    unlink( '/etc/apt/sources.list.tmp' ) if -e '/etc/apt/sources.list.tmp';
    closedir( DIR );
    print("sources.list - enabled\n");

    if (((defined $ARGV[1]) && ($ARGV[1] eq "--not-disable-syslists")) || ((defined $ARGV[2]) && ($ARGV[2] eq "--not-disable-syslists")))
    {
        print("Done.\n");
    }
    else
    {
        print("Disable syslists...\n");

        # disabling all mirrors
        if ($num>0)
        {
            opendir( DIR, $dir );
            foreach my $name (@enabled_list) {
                rename $name, $name . '.tmp' or die "Cannot disabling mirror: $!";
                open($fl, "<", $name . '.tmp');
                open NAME_MIRROR, '>', $name or die "Can't create $name: $!";
                while (my $line = <$fl>) {
                    my $t2 = substr($line, 0, 3);
                    if ($t2 eq'rpm') {
                        print NAME_MIRROR "#$line";
                    }
                    else {
                        print NAME_MIRROR $line;
                    }
                }
                close($fl);
                close NAME_MIRROR;
                unlink( $name . '.tmp' ) if -e $name . '.tmp';
            }
            closedir( DIR );
        }

        print("Done.\n");
    }
}

# show active mirror
sub show_active{
    if ((!defined $ARGV[1]) || ((!defined $ARGV[2]) && (($ARGV[1] eq 'active')||($ARGV[1] eq 'show')))){
        opendir( DIR, $dir );
        foreach my $name (sort readdir( DIR )) {
            if( $name =~ /\.list$/)
            {
                if ((trim($dir . $name) ne trim($ams_path)) && (trim($dir . $name) ne trim($exclude_list)))
                {
                    open(my $fl, "<", $dir . $name);
                    while (my $line = <$fl>) {
                        if (($line =~ /\[p1/) or ($line =~ /\[alt\]/)) {
                            my $t2 = substr($line, 0, 3);
                            if ($t2 eq'rpm') {
                                my $active_protocol = '';
                                if ($line =~ 'http:') {$active_protocol = 'http';}
                                if ($line =~ 'https:') {$active_protocol = 'https';}
                                if ($line =~ 'ftp:') {$active_protocol = 'ftp';}
                                if ($line =~ 'ftps:') {$active_protocol = 'ftps';}
                                if ($line =~ 'rsync:') {$active_protocol = 'rsync';}
                                if ($line =~ 'file:') {$active_protocol = 'file';}
                                $line =~ s/(.*\s+)(http|https|ftp|ftps|rsync|file):\/\///;
                                $line =~ s/\/.*//;
                                print("Active mirror: ".$line."Enabled protocol: ".$active_protocol."\n");
                                last;
                            }
                        }
                    }
                    close($fl);
                }
            }
        }
        closedir( DIR );
    }
}


# show local mirrors
sub show_mirror{
    if ((!defined $ARGV[1]) || ((!defined $ARGV[2]) && (($ARGV[1] eq 'mirror')||($ARGV[1] eq 'list')))){
        opendir( DIR, $dir );
        print "Local mirrors:\n";
        foreach my $name (sort readdir( DIR )) {
        if( $name =~ /\.list$/)
            {
                if ((trim($dir . $name) ne trim($ams_path)) && (trim($dir . $name) ne trim($exclude_list)))
                {
                    open(my $fl, "<", $dir . $name);
                    while (my $line = <$fl>) {
                        if (($line =~ /\[p1/) or ($line =~ /\[alt\]/)) {
                        $line =~ s/(.*\s+)(http|https|ftp|ftps|rsync|file):\/\///;
                        $line =~ s/\/.*//;
                        print $line;
                        last;
                        }
                    }
                    close($fl);
                }
            }
        }
        closedir( DIR );
    }
    else {
        print "Error: Unnecessary parameter.\nRun `ams --help` or `ams -h` for supported commands.\n";
    }
}

# Switch local mirror
sub switch_mirror {
    if (!defined $ARGV[1] || ((!defined $ARGV[2]) && ($ARGV[1] eq 'switch'))) { print "Error: Mirror not specified.\nRun `ams --help` or `ams -h` for supported commands.\n"; return 0; }
    #definition of an active mirror
    my $active_protocol = '';
    my $line2 = '';
    opendir( DIR, $dir );
    foreach my $name (sort readdir( DIR )) {
        if( $name =~ /\.list$/)
        {
            if ((trim($dir . $name) ne trim($ams_path)) && (trim($dir . $name) ne trim($exclude_list)))
            {
                open(my $fl, "<", $dir . $name);
                while (my $line = <$fl>) {
                    if (($line =~ /\[p1/) or ($line =~ /\[alt\]/)) {
                    my $t2 = substr($line, 0, 3);
                    if ($t2 eq'rpm') {
                        $active_mirror = $dir . $name; 
                        if ($line =~ 'http:') {$active_protocol = 'http:';}
                        if ($line =~ 'https:') {$active_protocol = 'https:';}
                        if ($line =~ 'ftp:') {$active_protocol = 'ftp:';}
                        if ($line =~ 'ftps:') {$active_protocol = 'ftps:';}
                        if ($line =~ 'rsync:') {$active_protocol = 'rsync:';}
                        if ($line =~ 'file:') {$active_protocol = 'file:';}
                        last;
                    }
                    }
                }
                close($fl);
            }
        }
    }
    closedir( DIR );

    #definition of an active mirror
    if ($disabled_sources_flag eq 0)
    {
        if ( (!defined $ARGV[2]) || (! $ARGV[2] =~ /^(http|https|ftp|ftps|rsync|file):\//) ) { print "Warning: Protocol not specified. Set default: http\n"; $line2 = 'http:'; }
        if ($line2 eq '') {$line2 = $ARGV[2].':';}
    }
    else
    {
        if ( (!defined $ARGV[3]) || (! $ARGV[3] =~ /^(http|https|ftp|ftps|rsync|file):\//) ) { print "Warning: Protocol not specified. Set default: http\n"; $line2 = 'http:'; }
        if ($line2 eq '') {$line2 = $ARGV[3].':';}
    }

    #find new mirror and check protocol
    my $new_mirror = '';
    my $flag_protocol = 0;
    $dir = $conf_list;
    $dir =~ s/\*\.list$//;
    opendir( DIR, $dir );

    foreach my $name (sort readdir( DIR )) {
        if( $name =~ /\.list$/)
            {
                if ((trim($dir . $name) ne trim($ams_path)) && (trim($dir . $name) ne trim($exclude_list)))
                {
                    open(my $fl, "<", $dir . $name);
                    while (my $line = <$fl>) {
                        if (($line =~ /\[p1/) or ($line =~ /\[alt\]/)) {
                            if ($disabled_sources_flag eq 0)
                            {
                                if (($line =~ $ARGV[1]) && ($new_mirror eq '')) {$new_mirror = $dir . $name;}
                                if (($line =~ $ARGV[1]) && ($line =~ $line2) && ($new_mirror ne "")) {$flag_protocol = 1; last;}
                            }
                            else
                            {
                                if (defined $ARGV[2])
                                {
                                    if (($line =~ $ARGV[2]) && ($new_mirror eq '')) {$new_mirror = $dir . $name;}
                                    if (($line =~ $ARGV[2]) && ($line =~ $line2) && ($new_mirror ne "")) {$flag_protocol = 1; last;}
                                }
                            }
                        }
                    }
                    close($fl);
                }
            }
    }
    closedir( DIR );

    # ------ block with different checks
    if ($disabled_sources_flag eq 0)
    {
        if ($new_mirror eq '') {print "Mirror '" . $ARGV[1] . "' not found.\n"; return 0;}
        if ($flag_protocol==0) {print "Protocol '" . $line2 . "' not found in '" . $ARGV[1] . "'\n"; return 0;}
    }
    else
    {
        if (defined $ARGV[2])
        {
            if ($new_mirror eq '') {print "Mirror '" . $ARGV[2] . "' not found.\n"; return 0;}
            if ($flag_protocol==0) {print "Protocol '" . $line2 . "' not found in '" . $ARGV[2] . "'\n"; return 0;}
        }
    }
    if (($new_mirror eq $active_mirror) && ($active_protocol eq $line2)) {print "The mirror and protocol have already been selected\n"; return 0;}  
    # check branch
    my $act_branch = trim(`rpm --eval %_priority_distbranch`);
    my $act_mirror = `rpm -qa | grep apt-conf-`;
    my $check_brach = 0;
    if ($act_mirror =~ $act_branch) {$check_brach = 1;}
    elsif (($act_branch =~ /p1/) && ($act_mirror =~ /branch/)) {$check_brach = 1;}
    else {$check_brach = 0;}
    if ($check_brach==0) {print "A difference in branches was detected. If you are using Sisyphus, install apt-conf-sisyphus.\n"; return 0;}
    # check arch
    my $arch = trim(`uname -m`);
    open(ARCH,$new_mirror);
    my @lines = <ARCH>;
    close ARCH;
    my $check_arch = 0;
    foreach my $arch_line (@lines) { if ($arch_line =~ $arch) {$check_arch = 1; last;} }
    if ($disabled_sources_flag eq 0)
    {
        if ($check_arch==0) {print "This mirror (" . $ARGV[1] . ") does not contain the required architecture.\n"; return 0;}
    }
    else
    {
        if (defined $ARGV[2]){ if ($check_arch==0) {print "This mirror (" . $ARGV[2] . ") does not contain the required architecture.\n"; return 0;} }
    }
    # check ams lists
    my $ams_list_package = trim(`rpm -qa | grep switcher-lists-`);
    my $check_ams_list;
    if (!defined $ams_list_package) {$check_ams_list = 1;}
    elsif ($ams_list_package =~ $act_branch) {$check_ams_list = 1;}
    elsif (($act_branch =~ /p1/) && ($ams_list_package =~ /branch/)) {$check_ams_list = 1;}
    else {$check_ams_list = 0;}
    if ($check_ams_list==0) {print "A branch difference was detected. You are using additional mirrors from a different branch.\n"; return 0;}
    # ------
    
    my $fl;
    opendir( DIR, $dir );

    if ($active_mirror ne '') {
        rename $active_mirror, $active_mirror . '.tmp' or die "Cannot switch mirror: $!";
        open($fl, "<", $active_mirror . '.tmp');
        open ACTIVE_MIRROR, '>', $active_mirror or die "Can't create $active_mirror: $!";
        while (my $line = <$fl>) {
            my $t2 = substr($line, 0, 3);
            if ($t2 eq'rpm') {
                print ACTIVE_MIRROR "#$line";
            }
            else {
                print ACTIVE_MIRROR $line;
            }
        }
        close($fl);
        close ACTIVE_MIRROR;
    }

    rename $new_mirror, $new_mirror . '.tmp' or die "Cannot switch mirror: $!";
    open($fl, "<", $new_mirror . '.tmp');
    open NEW_MIRROR, '>', $new_mirror or die "Can't create $new_mirror: $!";
    while (my $line = <$fl>) {
        if ($line =~ $line2){
            print NEW_MIRROR substr($line, 1);
            if ($cli_mirror eq '')
            {
                $line =~ s/(.*\s+)(http|https|ftp|ftps|rsync|file):\/\///;
                $line =~ s/\/.*//;
                $cli_mirror = $line;
            }
        }
        else {
            print NEW_MIRROR $line;
        }
    }
    close($fl);
    close NEW_MIRROR;
    unlink( $active_mirror . '.tmp' ) if -e $active_mirror . '.tmp';
    unlink( $new_mirror . '.tmp' ) if -e $new_mirror . '.tmp';
    unlink( $ams_path ) if -e $ams_path;
    closedir( DIR );

    if ($disabled_sources_flag eq 0) {
        print "Disabled: /etc/apt/sources.list\n";
        disabled_sources();
    }
    elsif ($cmd =~ /-(D|C|CD|DC)$/) {
        print "Disabled: /etc/apt/sources.list\n";
        disabled_sources();
    }

    #write config file
    if (( -e $conf_path . 'ams.conf') && ( -e $conf_path . 'alt-mirror-switcher.py'))
    {
        if ($cmd =~ /-(CN|C|NC|CD|DC|NDC|DNC|NCD|CND|DCN|CDN)$/)
            {print("Write config file - skiped\n");}
        else
        {
            print("Write config file...");
            my $config = Config::Tiny->read($conf_path . 'ams.conf');
            $config->{mirror}->{activ} = "cli: ".trim($cli_mirror);
            $config->{mirror}->{file} = $new_mirror;
            $config->{mirror}->{protocol} = $line2;
            if (!$config->write($conf_path . 'ams.conf')) {
                die "Error writing to config file: " . Config::Tiny->errstr;
            }
        }
    }

    print "\nDone.\n";
           
    return 0;
}

# Set Sisyphus archive date
sub set_archive{
    my $act_branch = trim(`rpm --eval %_priority_distbranch`);
    if ($act_branch =~ /sisyphus/) {
        if (!defined $ARGV[1] || ((!defined $ARGV[2]) && ($ARGV[1] eq 'set'))) { print "Error: Invalid launch parameters.\nRun `ams --help` or `ams -h` for supported commands.\n"; return 0; }
        my $my_argv;
        if ($disabled_sources_flag eq 0) { $my_argv = $ARGV[1]; } else { $my_argv = $ARGV[2]; }
        if ( (defined $my_argv) && ($my_argv =~ m/^[+-]?\d+$/) && (length($my_argv) == 8) ) {
            my $st_temp = $my_argv;
            my $myr = substr($st_temp, 0, 4);
            my $mmm = substr($st_temp, 4, 2);
            my $mda = substr($st_temp, 6, 2);
            print("year: $myr, month: $mmm, day: $mda\n");
            # Date check
            if (check_date($myr, $mmm, $mda)){
                substr($st_temp,4,0) = '/';
                substr($st_temp,7,0) = '/';
                opendir( DIR, $dir );
                # Find active mirror
                print("Find active mirror...\n");
                foreach my $name (sort readdir( DIR )) {
                if( $name =~ /\.list$/)
                {
                    if ((trim($dir . $name) ne trim($ams_path)) && (trim($dir . $name) ne trim($exclude_list)))
                    {
                        open(my $fl, "<", $dir . $name);
                        while (my $line = <$fl>) {
                            if (($line =~ /\[p1/) or ($line =~ /\[alt\]/)) {
                            my $t2 = substr($line, 0, 3);
                            if ($t2 eq'rpm') {
                                $active_mirror = $dir . $name;
                                last;
                            }
                            }
                        }
                       close($fl);
                    }
                }
                }
                print("Disable active mirror: $active_mirror\n");
                if ($active_mirror ne '') {
                    rename $active_mirror, $active_mirror . '.tmp' or die "Cannot switch mirror: $!";
                    open(my $fl, "<", $active_mirror . '.tmp');
                    open ACTIVE_MIRROR, '>', $active_mirror or die "Can't create $active_mirror: $!";
                    while (my $line = <$fl>) {
                        my $t2 = substr($line, 0, 3);
                        if ($t2 eq'rpm') {
                            print ACTIVE_MIRROR "#$line";
                        }
                        else {
                            print ACTIVE_MIRROR $line;
                        }
                    }
                    close($fl);
                    close ACTIVE_MIRROR;
                }
                unlink( $active_mirror . '.tmp' ) if -e $active_mirror . '.tmp';
                unlink( $ams_path ) if -e $ams_path;
                print("Set the date of the archive `Sisyphus`: $st_temp\n");
                open(my $fl, "<", $ams_path);
                open AMS_MIRROR, '>', $ams_path or die "Can't create $ams_path: $!";
                print AMS_MIRROR "# Sisyphus archive: $st_temp\n\n";
                print AMS_MIRROR "$archive_link$st_temp$archive_end[0]\n";
                print AMS_MIRROR "$archive_link$st_temp$archive_end[1]\n";
                print AMS_MIRROR "$archive_link$st_temp$archive_end[2]\n";
                close($fl);
                close AMS_MIRROR;
                closedir( DIR );

                if ($disabled_sources_flag eq 0) {
                    print "Disabled: /etc/apt/sources.list\n";
                    disabled_sources();
                }
                print "\nDone.\n";

                return 0;
            }
            else{
                print "Error: Incorrect date.\n";
            }
        }
        else
        {
         if ($disabled_sources_flag eq 0)
         {
            print "Error: `$ARGV[1]` is not int(8).\n"; return 0;
         }
         else
         {
            print "Error: `$ARGV[2]` is not int(8).\n"; return 0;
         }
        }
    }
    else{
         print "Error: You don`t use Sisyphus.\n"; return 0; }
}

# Show usage information
sub show_usage {
    print <<"HELP";
-----------------------
ALT Mirror Switcher CLI
-----------------------

Usage: ams <SUBCOMMANDS> active|show
       ams <SUBCOMMANDS> mirror|list
       ams <SUBCOMMANDS> switch <mirror> <http|https|ftp|ftps|rsync|file>
       ams <SUBCOMMANDS> set <yyyymmdd>
       ams <SUBCOMMANDS> sourceson <--not-disable-syslists>

COMMANDS:
  active|show - Showing active mirror and enabled protocol
  mirror|list - Showing local update mirrors
  switch <mirror> <http|https|ftp|ftps|rsync|file> - Switching local update mirrors with needs protocols (default: http)
  set <yyyymmdd> - Set Sisyphus archive date, for example: `ams set 20260509`
  sourceson - enable sources.list and disabled all system lists
  sourceson --not-disable-syslists - enable sources.list and do not disable all system lists
  -h, --help - Show help and exit
  -v, --version - Show version number

SUBCOMMANDS:
  -N - Not disable sources.list
  -ND,-DN - Not disable sources.list and not do automatic restore active list if GUI ams and conf exist
  -D - not do automatic restore active list if GUI ams and conf exist
  -С - do not write config file
  -CN,-NC - not write config file and not disable sources.list
  -CD,-DC - not write config file and not do automatic restore active list if GUI ams and conf exist
  -NDC,-DNC,-NCD,-CND,-DCN,-CDN - do not write config file and not do automatic restore active list if GUI ams and conf exist and not disable sources.list

HELP
    exit 0;
}

# Functions with return
if(( $cmd eq 'mirror' ) || ( $cmd eq 'list' )) {
    show_mirror( @ARGV );
}elsif( $cmd eq 'switch' ) {
    switch_mirror( @ARGV );
}elsif( $cmd eq 'set' ) {
    set_archive( @ARGV );
}elsif( $cmd eq 'sourceson' ) {
    sourceson( @ARGV );
}elsif( ($cmd eq 'active' ) || ( $cmd eq 'show' ) ) {
    show_active( @ARGV );
}elsif( $cmd =~ /-(h|-help)$/ ) {
    show_usage();
}
elsif( $cmd =~ /-(v|-version)$/ ) {
    die "Version - $version\n";
}elsif( $cmd =~ /-(N|ND|DN|D|CN|NC|C|CD|DC|NDC|DNC|NCD|CND|DCN|CDN)$/ ) {
    if( scalar @ARGV == 1 ) {
        die "Run `ams --help` or `ams -h` for supported commands.\n";
    }
    elsif(($cmd2 eq 'mirror')  || ( $cmd2 eq 'list' )){
        show_mirror( @ARGV );
    }
    elsif($cmd2 eq 'switch' ){
        switch_mirror( @ARGV );
    }
    elsif($cmd2 eq 'set' ){
        set_archive( @ARGV );
    }
    elsif($cmd2 eq 'sourceson' ){
        sourceson( @ARGV );
    }
    elsif(($cmd2 eq 'active') || ( $cmd2 eq 'show' ) ){
        show_active( @ARGV );
    }
    elsif($cmd2 =~ /-(h|-help)$/){
        show_usage();
    }
    elsif( $cmd2 =~ /-(v|-version)$/ ) {
        die "Version - $version\n";
    }
}elsif( scalar @ARGV == 0 ) {
    die "Run `ams --help` or `ams -h` for supported commands.\n";
}else {
    die "Unknown command `@ARGV`.\nRun `ams --help` or `ams -h` for supported commands.\n";
}

__END__
