#!/usr/bin/perl

use strict;
use utf8;

use Excel::Template;
use Text::Tabs;

local $tabstop = 8;

# セパレータから取得範囲を計算
sub field_range {
    local $_ = expand(shift);
    my $range = 0;
    my $range_list = [];
    while (/\G(\s+)(\S+)/g) {
	my $begin = $range + length($1);
	my $length = length($2);
	push(@$range_list, [$begin, $length]);
	$range = $begin + $length;
    }
    return $range_list;
}

# 取得範囲のリストを元に文字列を切り出し
sub get_fields {
    my ($line, $range_list) = @_;
    my @result = ();
    foreach my $range (@$range_list) {
	push(@result, substr($line, $range->[0], $range->[1]));
    }
    return @result;
}

# 個々のDESC出力を解析
sub parse_desc {
    my ($ifh, $table_info) = @_;
    <$ifh>; # skip a line.
    my $sep = <$ifh>;
    my $range_list = field_range($sep);
    my $column_list = [];
    my $index = 1;
    while (<$ifh>) {
	last if (/^$/);
	$_ = expand($_);
	my ($name, $not_null, $type) = map {
	    s/\s+$//;
	    $_;
	} get_fields($_, $range_list);
	push(@$column_list, { index => $index++,
			      column_name => $name,
			      not_null => $not_null,
			      type => $type } );
    }
    $table_info->{column_list} = $column_list;
}

sub parse_desc_list {
    my $ifile = shift;
    open(my $ifh, $ifile) or die "Can't open $ifile ($!)";
    my $index = 1;
    my $table_list = [];
    local $_;
    while (<$ifh>) {
	if (/^SQL>\s+desc\s+([\w\.]+)/) {
	    my $table_info = { index => $index++, table_name => $1 };
	    parse_desc($ifh, $table_info);
	    push(@$table_list, $table_info);
	}
    }
    close($ifh);
    return $table_list;
}

sub main {
    my ($ifile) = @ARGV;
    if (! -f $ifile) {
	print STDERR "Usage: $0 DESC_LIST_FILE\n";
	exit(1);
    }
    my $table_list = parse_desc_list($ifile);
    (my $ifile = $0) =~ s/\.pl$/.xml/ or die "Can't get XML template";
    my $tmpl = new Excel::Template(filename => $ifile, use_unicode => 1);
    $tmpl->param(table_list => $table_list);
    $tmpl->write_file("tables.xls");
}

main;
