use strict;
use warnings;
use Getopt::Long;

sub main() {
  my $outDir;
  Getopt::Long::GetOptions(q{out=s} => \$outDir) or die;
  die($outDir) unless defined($outDir) and $outDir ne q{};
  open(my $main, q{>}, qq{$outDir/main.xml}) or die();
  my $xmlHeader = <>;
  print($main $xmlHeader);
  local($/);
  my $in = <>;  # slurp rest of file
  if ($in =~ m{^(<multilat-output.+?>)}gs) {
    my $multilatAttrs = $1;
    if ($multilatAttrs =~ m{retentionRatesFile="(.+?)"}) {
      CopyFile($outDir, $1);
    } else {die($multilatAttrs);}
    if ($multilatAttrs =~ m{languageFiles="(.+?)"}s) {
      my $languageFiles = $1;
      $languageFiles =~ s{^\s+}{};
      my @files = split(m{\s+}, $languageFiles);
      foreach my $file (@files) {CopyFile($outDir, $file);}
    } else {die($multilatAttrs);}
    print($main $multilatAttrs, qq{\n});
  } else {die();}
  if ($in =~ m{\G\s*(<retention-rates file.+?)>.+?</retention-rates>}gs) {
    print($main $1, qq{/>\n});
  } else {die();}
  my $languagesOut;
  if ($in =~ m{\G\s*<languages>}gs) {
    print($main qq{<languages href="languages.xml"/>\n});
    open($languagesOut, q{>}, qq{$outDir/languages.xml}) or die();
    print($languagesOut qq{<?xml version="1.0" encoding="utf-8"?>
<languages>});
  } else {die();}
  while ($in =~ m{\G\s*<language fileName="(.+?)">\s*<id>(.+?)</id>(.+?)</language>}gsc) {
    my $fileName = $1;
    my $id = $2;
    my $data = $3;
    my $subfileName = qq{language_$id.xml};
    print($languagesOut qq{<language sourceFileName="$fileName" id="$id" href="$subfileName"/>\n});
    open(my $languageOut, q{>}, qq{$outDir/$subfileName}) 
      or die(qq{$outDir/language_$id});
    print($languageOut qq{<?xml version="1.0" encoding="utf-8"?>
<language sourceFileName="$fileName" id="$id">
$data
</language>
});
    close($languageOut);
  }
  if ($in =~ m{\G\s*</languages>}gs) {
    print($languagesOut qq{</languages>\n});
    close($languagesOut);
  } else {die();}
  if ($in =~ m{\G\s*<cluster-cycles>}gs) {
    print($main qq{<cluster-cycles>\n});
  } else {die();}
  my $nextCycle = 1;
  my $compCache = {}; 
  while ($in =~ m{\G\s*<cluster-cycle nLanguages=".+?">(.+?)</cluster-cycle>}gsc) {
    my $cycle = $1;
    my $cycleRef = qq{cycle$nextCycle.xml};
    print($main qq{<cluster-cycle href="$cycleRef">\n});
    if ($cycle =~ m{(<language-merge languages=".+?" distance-reduction=".+?")>}s) {
      print($main qq{$1/>\n});
    }
    print($main qq{</cluster-cycle>\n});
    open(my $cycleOut, q{>}, qq{$outDir/$cycleRef}) or die($cycleRef);
    print($cycleOut qq{<?xml version="1.0" encoding="utf-8"?>
<cluster-cycle n="$nextCycle">
});
    my $nextComp = 1;
    while ($cycle =~ m{\G\s*<language-compare languages="(.+?)">(.+?)</language-compare>}gcs) {
      my $langs2 = $1;
      my $comparison = $2;
      my $cached = $compCache->{$langs2};
      if (defined($cached)) {
        print($cycleOut qq{<language-compare languages="$langs2" href="$cached">\n});
        if ($comparison =~ m{(<cache.+?/>)}) {
          print($cycleOut qq{$1\n});
        } else {die($comparison);}
      } else {
        my $href = qq{cycle${nextCycle}_comp$nextComp.xml};
        $compCache->{$langs2} = $href;
        print($cycleOut qq{<language-compare languages="$langs2" href="$href">\n});
        if ($comparison =~ m{(<monteCarlo.+?/>)}) {
          print($cycleOut qq{$1\n});
        } else {die($comparison);}
        open(my $compout, q{>}, qq{$outDir/$href}) or die($href);
        print($compout qq{<?xml version="1.0" encoding="utf-8"?>
<language-compare languages="$langs2">
$comparison
</language-compare>
});
        close($compout);
      }
      print($cycleOut qq{</language-compare>\n});
      $nextComp++;
    }
    print($cycleOut qq{</cluster-cycle>\n});
    close($cycleOut);
    $nextCycle++;
  }
  print($main qq{</cluster-cycles>
</multilat-output>
});
  close($main);
}

sub CopyFile($$) {
  my $outDir = shift(@_);
  my $name = shift(@_);
  if ($name =~ m{^(.+)/[^/]+$}) {
    mkdir(qq{$outDir/$1});
  }
  system(qq{cp $name $outDir/$name});
  if ($? == -1) {
    print "failed to execute: $!\n";
  } elsif ($? & 127) {
   printf "child died with signal %d, %s coredump\n",
       ($? & 127),  ($? & 128) ? 'with' : 'without';
  }
}

main();
