#!/usr/bin/perl -w -C63

use strict;
use 5.026;
use warnings;
use utf8;
use open qw/:std :utf8/;

use Archive::Zip qw( :ERROR_CODES :CONSTANTS );
Archive::Zip::setErrorHandler( \&myErrorHandler );
use Archive::Zip::MemberRead;
sub myErrorHandler () { }
use Cwd;
use File::Find;
no warnings qw(File::Find);
use File::Type;
use Digest::SHA qw(sha256);
use Data::Dump qw(dump);
use File::Copy qw(cp);

my $workDir = getcwd;

mkdir "./phobos" or die;
mkdir "./graphicsMod" or die;
mkdir "./spectatorMod" or die;
mkdir "./otherMod" or die;
mkdir "./clean" or die;
mkdir "./depricate" or die;

# заканчиваем поиск на компе.

# находим все похожее на карты и складываем в список
# извлекаем из архива название левела
# карты фобоса -- droid.json
# графический мод *decals.txt или tile-00.png
# мод на спека rules.js
# хлам -- остальные .js и json файлы, несколько .lev в .lev много уровней, игра не запускается с картой.

# - на выходе у нас массив с именем левела, хешсуммой, путем и категорией.
my @maps;
my %listHashs;
my @dirs = ( "/home/", "/media/" );

#my @dirs = qw(/home/vitya/.local/share/warzone2100/maps);
my $ft  = File::Type->new();
my $sha = Digest::SHA->new(256);
find( \&wanted, @dirs );

sub wanted {
    return unless -f;               #Must be a file
    return unless /\d+c[-].*\.wz$/; #Must end with `0c-`prefix and `.wz` suffix.
    $sha->addfile("$File::Find::name");
    my $hash = $sha->hexdigest;
	return if exists $listHashs{$hash};
	$listHashs{$hash} = "true";
    if ( $ft->checktype_filename($File::Find::name) ne "application/zip" ) {
        push( @maps,
            { read => "NotZip", file => $File::Find::name, hash => $hash } );
        return;
    }
    my $somezip = Archive::Zip->new();
    unless ( $somezip->read($File::Find::name) == AZ_OK ) {
        push( @maps,
            { read => "brokenZip", file => $File::Find::name, hash => $hash } );
        return;
    }
	
    my @members  = $somezip->members();
    my $specMod  = "false";
    my $phobos   = "false";
    my $grapMod  = "false";
    my $multiLev = "false";
	my $allMod = "false";
    my $levName  = "";
	my $players = "";
	my $time = 0;
    foreach (@members) {
        if ( $_->fileName =~ /rules.js$/ ) { $specMod = "true"; }
        if ( $_->fileName =~ /tile-\d+.png$/ || $_->fileName =~ /decals.txt$/ )
        {
            $grapMod = "true";
        }
        if ( $_->fileName =~ /droid.json$/ ) { $phobos = "true"; }
		if ($_->fileName =~ /(\.js$)|(\.json$)|(\.csv$)|(\.txt$)|(\.slo$)|(\.wrf)/){$allMod = "true"}
        if ( $_->fileName =~ /.lev$/ ) {
			$time = $_->{lastModFileDateTime}; 
            my $fhLev = $_->readFileHandle();
            while ( defined( my $line = $fhLev->getline() ) ) {
                if (
                    (
                           $line =~ /level\s+(Sk-)?(.*)-T\d\s?$/
                        || $line =~ /level\s+(Sk-)?(.*)\s?$/
                    )
                    && $levName ne $2
                  )
                {
                    if ( $levName ne "" ) { $multiLev = "true" }
                    $levName = $2;

                }
				if ($line =~ /players\s+(\d\d?)/){
					$players = $1;
				}
            }
            $fhLev->close();
        }
    }
	if ( !$players ){$players =0};
    if ( !$levName || !$players ) {$multiLev = "true"}
    push(
        @maps,
        {
            specMod  => $specMod,
            phobos   => $phobos,
            grapMod  => $grapMod,
            file     => $File::Find::name,
            hash     => $hash,
            levName  => $levName,
            multiLev => $multiLev,
			players => $players,
			allMod => $allMod,
			time => $time+252460801
        }
    );
    return;
}

#dump @maps;
say scalar @maps;

foreach my $map (@maps) {
	my $path = "./clean/";
	if ($map->{read}){next};
	if ($map->{multiLev} eq "true") {$path = "./depricate/"};
	if ($map->{allMod} eq "true"){$path = "./otherMod/"};
	if ($map->{specMod} eq "true"){$path = "./spectatorMod/"};
	if ($map->{grapMod} eq "true"){$path = "./graphicsMod/"};
	if ($map->{phobos} eq "true"){$path = "./phobos/"};
	
	my $newName = $path.$map->{players}."c-".$map->{levName}."-".$map->{hash}.".wz";
	cp($map->{file}, $newName );
	my $atime = my $mtime = $map->{time};
	utime $atime, $mtime, $newName;
}
