#!/usr/bin/perl
# Copyright 1999-2014. Parallels IP Holdings GmbH. All Rights Reserved.

use strict;

# Prefer internal modules over external
use lib '.';
use lib 'shared_legacy';

use Agent;
use AgentConfig;
use CompatArgParse;
use Logging;
use XmlNode;
use DumpComposer;
use DumpAgentConfig;

use sigtrap qw(die normal-signals);
use POSIX qw(:signal_h);
use Carp qw( confess );

sub printHelp {
  print <<'HELP';

Usage:
  $0 [<options>]

Options:
  -h |--help                      This help.

  -sd|--shallow-dump              Lightweight dump for building migration list.
                                  Contains resellers, customers and subscriptions.

  -dr|--dump-resellers=<list>     Сomma-separated list of resellers to dump
  -dc|--dump-clients=<list>       Сomma-separated list of clients to dump
  -dd|--dump-domains=<list>       Сomma-separated list of domains to dump

  -cs|--convert-subdomain=<mode>  Convert cPanel subdomains in specified mode:
                                  - "subdomain": convert to Plesk subdomain (mailboxes are skipped)
                                  - "addon-domain": convert to Plesk addon domain
                                  - "addon-domain-if-mail": convert to Plesk addon domain if subdomain has mail,
                                    and to Plesk subdomain otherwise.

  -ca|--convert-alias=<mode>      Convert cPanel aliases in specified mode:
                                  - "alias": convert to Plesk domain alias (mailboxes are skipped)
                                  - "addon-domain": convert to Plesk addon domain
                                  - "addon-domain-if-mail": convert to Plesk addon domain if alias has mail.

  -v |--verbosity=<1-5>           Verbosity level. Default is 5.

HELP
}

sub main {
  my $sigset = POSIX::SigSet->new;
  sigprocmask( SIG_SETMASK, $sigset );

  $SIG{__DIE__} =  \&confess;

  my %arg_opts = (
    '--help|-h'                => '',
    '--shallow-dump|-sd'     =>  '',
    '--dump-resellers|-dr'     => 's',
    '--dump-clients|-dc'       => 's',
    '--dump-domains|-dd'       => 's',

    # Legacy unused options for compatibility with Plesk Migrator
    '--dump-all|-da'           => '',
    '--configuration-only|-co' => '',
    '--server'                 => '',

    '--convert-subdomain|-cs'      => 's',
    '--convert-alias|-ca'          => 's',
    '--verbosity|-v'           => 's'
  );

  my $args = CompatArgParse::parse( \@ARGV, \%arg_opts );

  if ( exists $args->{'help'} ) {
    printHelp();
    return 0;
  }

  # set up default verbosity
  Logging::setVerbosity( 3 );
  if ( exists $args->{'verbosity'} ) {
    Logging::setVerbosity( $args->{'verbosity'} );
  }

  Logging::setXmlLogging();

  my $convertSubdomain;
  if ( exists $args->{'convert-subdomain'} ) {
    $convertSubdomain = $args->{'convert-subdomain'};
  } else {
    $convertSubdomain = DumpAgentConfig::getValue('convert-subdomain')
  }
  Agent::setConvertSubdomainMode($convertSubdomain);

  my $convertAlias;
  if ( exists $args->{'convert-alias'} ) {
    $convertAlias = $args->{'convert-alias'};
  } else {
    $convertAlias = DumpAgentConfig::getValue('convert-alias')
  }
  Agent::setConvertAliasMode($convertAlias);

  my ($domains, $clients, $resellers) = (undef, undef, undef);
  unless (exists $args->{'dump-all'}
    || exists $args->{'dump-resellers'}
    || exists $args->{'dump-clients'}
    || exists $args->{'dump-domains'}
    || exists $args->{'shallow-dump'})
  {
    printHelp();
    return 0;
  } elsif (exists $args->{'dump-all'} || exists $args->{'shallow-dump'}) {
    Logging::debug("Selected all objects");
  } else { # at least one of object selection argument was passed
    $domains = [ parseSelectedObjectsArg($args, 'dump-domains', 'domains') ];
    $clients = [ parseSelectedObjectsArg($args, 'dump-clients', 'clients') ];
    $resellers = [ parseSelectedObjectsArg($args, 'dump-resellers', 'resellers') ];
  }

  my $dumpNode;
  if ( exists $args->{'shallow-dump'} ) {
    Agent::setShallowDumpMode();
    $dumpNode = Dumper::makeShallowDump(
      AgentConfig::cwd()
    );
  } else {
    $dumpNode = Dumper::makeDump(
      AgentConfig::cwd(), $resellers, $clients, $domains, 1, undef, undef, undef
    );
  }

  if ( ref($dumpNode) =~ /XmlNode/ ) {
    Logging::debug("Migration dump is successfully saved.");
  } else {
    Logging::error("Migration dump is not saved.");
  }

  return 0;
}

sub parseSelectedObjectsArg {
  my ($args, $argumentName, $objectsDescription) = @_;

  my @objects;

  if (exists $args->{$argumentName}) {
    my $value = $args->{$argumentName};
    if ($value eq "-") {
      $value = <STDIN>;
      chomp $value;
    }
    @objects = split( /\s*,\s*/, $value);
  } else {
    # argument was not passed, so no objects are selected
  }

  Logging::debug("Selected $objectsDescription: " . join(", ", @objects));
  return @objects;
}

sub writeMigrationResult{
  my $sessionPath = AgentConfig::cwd();
  Logging::serializeXmlLog("$sessionPath/migration.result");
  return;
}

my $exitcode = main();
writeMigrationResult();
exit( $exitcode );

