package MexCatalog;

use utf8;
use strict;
use warnings;

use Dancer ':syntax';
use File::Slurp qw/read_file write_file/;
use File::Copy;
use File::Path 'make_path';
use Data::Dumper;
use Cwd;
use Encode;
use Encode::Guess;
use Dancer::Plugin::FlashMessage;
use YAML::Syck;
$YAML::Syck::ImplicitUnicode = 1;

use Data::Dumper;

#$ENV{PATH} .= ':/usr/local/bin'; 
my $local = '/usr/local/bin';

our $VERSION = '0.1';
my $BASEDIR = '/home/natura/mex/public';
my $USRDIR = $BASEDIR.'/users';
my $WEBDIR = '/mex/users';
my $catalogfile = $BASEDIR.'/catalogue';
#my $catalogfile = "$BASEDIR/mex_catalogue_dump"; ##FIXME rever

system("$local/pass-logue '$BASEDIR' -root='$BASEDIR' -cata='$catalogfile'");

my %users;
_readusers();

get '/' => sub {
	redirect '/problems';
};

get '/problems' => sub {
	my $data = __read_catalog($catalogfile);
	#print STDERR Dumper($data)."\n";

	my $catalog;
	my @letters = 'a'..'z';

	foreach (keys %$data) {
		if ($_ =~ m/^__/) {
			delete $data->{$_};
			next;
		}

		if (ref($data->{$_}) eq 'ARRAY') {
			foreach my $i (@{$data->{$_}}) {
				my $dir = $i->{'dir'};
				my $name = $_;

				my $sdir = $dir.'/'.$name;
				if(-e $sdir) {
					my @l = split m/users/, $sdir;
					$i->{'src_link'} = $WEBDIR.$l[1] if $l[1];
				}

				$name =~ s/\.[^.]+$//;

				my $tdir = $dir.'/'.$name.'.tex';
				if(-e $tdir) {
					my @l = split m/users/, $tdir;
					$i->{'tex_link'} = $WEBDIR.$l[1];
					#print STDERR "DEBUG '".$tdir."' => '".$i->{'tex_link'}."'\n";
				} else {
					$tdir = $dir.'/OUT/'.$name.'.tex';
					if(-e $tdir) {
						my @l = split m/users/, $tdir;
						$i->{'tex_link'} = $WEBDIR.$l[1];
	                                        #print STDERR "DEBUG '".$tdir."' => '".$i->{'tex_link'}."'\n";
					}
				}


				my $pdir = $dir.'/'.$name.'.pdf';
                                if(-e $pdir) {
                                        my @l = split m/users/, $pdir;
                                        $i->{'tex_link'} = $WEBDIR.$l[1];
                                        #print STDERR "DEBUG: '".$pdir."' => '".$i->{'pdf_link'}."'\n";
                                } else {
                                        $pdir = $dir.'/OUT/'.$name.'.pdf';
                                        if(-e $pdir) {
                                                my @l = split m/users/, $pdir;
                                                $i->{'pdf_link'} = $WEBDIR.$l[1];
                                                #print STDERR "DEBUG: '".$pdir."' => ' ".$i->{'pdf_link'}."'\n";
                                        }
                                }
			}
		}

		if ($_ =~ m/^(\w)/) { $catalog->{lc $1}->{$_} = $data->{$_}; }
		else { $catalog->{'_'}->{$_} = $data->{$_}; }
	}

	template 'problems' => {
			current => 'problems',
			catalog => $catalog,
			letters => [@letters],
		};
};

sub __read_catalog {
	my $filename = shift;
	return unless $filename;
	no strict;
	no warnings;

	my $c = read_file $filename;
	my $d = eval $c;

	return $d;
}

post '/login' => sub {
        my $action = param 'action';

        if($action =~ m/Login/) {
                my $username = param 'username';
                my $password = param 'password';

                if (defined($users{lc($username)}) and $users{lc($username)} eq $password) {
                        session username => $username;
                        __handle_dir($username);
                        flash msg => 'Login Successful!';
                } else {
                        flash msg => 'Login failed!';
                }

                session 'filename' => '';
                session 'source' => '';

                redirect '/';
        } else {
                redirect '/register';
        }

   my $username = param 'username';
   my $password = param 'password';
};

get '/logout' => sub {
   session->destroy;
   flash msg => 'Logout Successufl';
   redirect '/';
};

get '/register' => sub {
        template 'register' => {current=>'register'};
};

post '/register' => sub {
        my $username = param 'rusername';
        my $password = param 'rpassword';
        my $result = _adduser($username, $password);
        print STDERR "DEBUG: Registering user ".$username.", result: ".$result."\n";
        if($result == 0) { flash msg => 'Registration complete!'; }
        elsif($result == 3) { flash msg => 'That login was already used!';  }
        else { flash msg => 'Unable to register user.';  }
        redirect '/';
};

sub __handle_dir {
   my ($username) = @_;

   my $target = "$USRDIR/$username";
   make_path($target) unless -e $target;

   session userdir => $target;
}

# _readusers() : Fills the %users variable.
sub _readusers{ # TODO Switch to a "SELECT * FROM users" with SQLite
  my $passwd = $USRDIR.'/passwd';
  open(A,"<",$passwd) or die("cant find $passwd\n");
    while(<A>){
      next if /^#/;
      if(/^(\S+?):([^:\s]+)/){ $users{$1}=$2 }
    }
  close A;
}

# _adduser(Login, Password) : Adds a user to the passwd file.
sub _adduser{ # TODO Switch to SQLite
	my $passwd = $USRDIR.'/passwd';
        if(scalar(@_) < 2 || !defined($USRDIR)) { return 1; }
        my $username = shift(@_);
        my $password = shift(@_);

        open(A,"<",$passwd) or die("Error: Can't find '".$passwd."'.\n", 2);
        while(<A>){
                my $user = $_;
                # Ignore comments
                next if($user =~ m/^#/);
                # Fail if username exists
                if($user =~ m/$username:.*/) { return 3; }
        }
        close(A);

        open(A, ">>",$passwd) or die("Error: Can't write on '".$passwd."'.\n", 4);
        print A $username.":".$password."\n";
        close(A);

	_readusers();
        return 0;
}

true;
