#!/usr/bin/perl -w
use strict;
use warnings;
use Text::CSV;
use IO::Handle;

# TODO does not work if a field contains a newline

if (!$ENV{opts_got}) {
    exec 'o', $0, @ARGV;
    die "csvsplit: could not exec config loader: o\n";
}

my $head = $ENV{head};
my $dos = $ENV{dos};
my $missing = $ENV{missing};
my $flush = $ENV{flush};
my $sep = $ENV{sep};
my ($use_head_names) = $head eq 'use';
my $eol = $dos ? "\r\n" : "\n";

my @outputs = @ARGV;
my @out_fhs;
my %out_fhs_ix;
for my $i (0..$#outputs) {
    my $file = $outputs[$i];
    open my $fh, '>', $file
        or die "csvsplit: open failed >$file: $!\n";
    if ($flush) {
        $fh->autoflush;
    }
    $out_fhs[$i] = $fh;
    $out_fhs_ix{$file} = $fh;
}

#my $csv = Text::CSV->new({ binary => 1, always_quote => 1, blank_is_undef => 1 })
my $csv = Text::CSV->new({ binary => 1, sep_char => $sep })
    or die "csvsplit: Cannot use CSV: ".Text::CSV->error_diag;
$csv->eol($eol);

my $in = \*STDIN;
binmode($in, ":utf8");

sub filename {
    my ($name) = @_;
    $name =~ s/\A\s+//;
    $name =~ s/\s+\z//;
    $name =~ s/[^A-Za-z0-9]+/_/g;
    $name = lc $name;
    return $name;
}

my $header;
my %header_ix;
if ($head) {
    $header = $csv->getline($in);
    if (!$header) {
        $csv->eof or die $csv->error_diag();
        die "csvsplit: expected header\n";
    }
    for my $i (0..$#$header) {
        my $filename = filename($header->[$i]);
        $header_ix{$filename} = $i;
    }
}

while(1) {
    my $row = $csv->getline($in);
    if (!$row) {
        $csv->eof or die $csv->error_diag();
        last;
    }
    for my $i (0..$#outputs) {
        my $filename = $outputs[$i];
        my $fh = $out_fhs[$i];
        my $x;
        if ($use_head_names) {
            my $j = $header_ix{$filename};
            if (!defined $j && $missing) {
                $x = '';
            } else {
                $x = $row->[$j];
            }
        } else {
            $x = $row->[$i];
        }
        if (!defined $x) {
            if ($missing) {
                $x = '';
            } else {
                die "csvsplit: missing field: $filename at line $.\n";
            }
        }
        print $fh $x, "\n";
    }
}
