#! /usr/bin/env perl
#
# Copyright (C) 2008-2025 Alexis Bienvenüe <paamc@passoire.fr>
#
# This file is part of Auto-Multiple-Choice
#
# Auto-Multiple-Choice is free software: you can redistribute it
# and/or modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation, either version 2 of
# the License, or (at your option) any later version.
#
# Auto-Multiple-Choice is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Auto-Multiple-Choice.  If not, see
# <http://www.gnu.org/licenses/>.

use warnings;
use 5.012;

use Getopt::Long;
use AMC::Basic;

my $cr_dir   = '';
my $liste    = '';
my $data_dir = '';
my $list     = '';
my $set      = '';
my $set_from = '';
my $student  = '';
my $copy     = '';
my $id       = undef;
my $raw      = '';

GetProjectOptions(
    ":cr:dir|cr=s"                => \$cr_dir,
    ":listeetudiants:dir|liste=s" => \$liste,
    ":data:dir|data=s"            => \$data_dir,
    "list!"                       => \$list,
    "raw!"                        => \$raw,
    "set!"                        => \$set,
    "set-from=s"                  => \$set_from,
    "student=s"                   => \$student,
    "copy=s"                      => \$copy,
    "id=s"                        => \$id,
);

debug("AMC-association / DEBUG") if (get_debug());

if ( ( $list ? 1 : 0 ) + ( $set ? 1 : 0 ) + ( $set_from ? 1 : 0 ) > 1 ) {
    die "Cannot select more that one options from --list, --set, --set-from";
}

if ($list) {
    require AMC::Data;

    my $data    = AMC::Data->new($data_dir);
    my $assoc   = $data->module('association');
    my $capture = $data->module('capture');
    $data->begin_read_transaction('ALST');
    my @list;
    if ($raw) {
        @list = map { [ $_->{student}, $_->{copy} ] } ( @{ $assoc->list() } );
    } else {
        @list = $capture->student_copies();
    }
    print "Student\tID\n";
    for my $c (@list) {
        print studentids_string(@$c) . "\t";
        my $manual = $assoc->get_manual(@$c);
        my $auto   = $assoc->get_auto(@$c);
        if ( defined($manual) ) {
            print $manual;
            print " (manual";
            if ( defined($auto) ) {
                print ", auto=" . $auto;
            }
            print ")\n";
        } elsif ( defined($auto) ) {
            print $auto. " (auto)\n";
        } else {
            print "(none)\n";
        }
    }
    $data->end_transaction('ALST');
} elsif ($set) {
    require AMC::Data;

    my $data  = AMC::Data->new($data_dir);
    my $assoc = $data->module('association');
    $data->begin_transaction('ASET');
    $copy=0 if($copy eq '');
    $assoc->set_manual( $student, $copy, $id );
    $data->end_transaction('ASET');
} elsif($set_from) {
    require AMC::Data;
    require Text::CSV;

    if ( !-f $set_from ) {
        die "Could not find file $set_from";
    }
    die "Needs a column name for the sheet numbers" if ( !$student );
    die "Needs a column name for the student IDs"   if ( !$id );

    my $csv = Text::CSV->new( { binary => 1, auto_diag => 1 } );
    open my $fh, "<:encoding(utf8)", $set_from
      or error("Error opening $set_from: $!");
    my %headers = map { $_ => 1 } (
        $csv->header(
            $fh, { sep_set => [ ";", ",", "\t" ], munge_column_names => 'none' }
        )
    );
    for my $h ( $student, $copy, $id ) {
        if ( $h && !$headers{$h} ) {
            die "Could not find column \"$h\" in the CSV file";
        }
    }
    my $data  = AMC::Data->new($data_dir);
    my $assoc = $data->module('association');
    $data->begin_transaction('ASTF');
    while ( my $row = $csv->getline_hr($fh) ) {
        my $s = $row->{$student};
        my $c = 0;
        $c = $row->{$copy} if ($copy ne '');
        my $i = $row->{$id};
        $i = undef if ( $i eq '' );
        if ( $s ne '' ) {
            $assoc->set_manual( $s, $c, $i );
        } else {
            debug "Warning: no student found";
        }
    }
    $data->end_transaction('ASTF');
    close $fh;
} else {
    require AMC::Gui::Association;

    my $g = AMC::Gui::Association::new(
        cr       => $cr_dir,
        liste    => $liste,
        data_dir => $data_dir,
        global   => 1,
    );

    Gtk3->main;
}

