#!/usr/bin/perl

use strict;
use warnings;
use Data::Random qw(:all);
use Getopt::Long::Descriptive;

my( $opt, $usage ) = describe_options(
    "$0 %o",
    [ 'dsn=s',      'dsn, for example dbi:SQLite:test.db', { required     => 1 } ],
    [ 'number|n=i', 'number of entries in each table',     { default      => 100 } ],
    [ 'help',       'print usage message and exit',        { shortcircuit => 1 } ],
);

print( $usage->text ), exit if $opt->help;

my $schema = "My::Schema";
$schema->connection( $opt->dsn );

my @source_order =
    sort {
        scalar (grep { $_->{attrs}{is_depends_on} }
             map { $schema->source($a)->relationship_info($_) }
                   $schema->source($a)->relationships) <=>
        scalar (grep { $_->{attrs}{is_depends_on} }
             map { $schema->source($b)->relationship_info($_) }
                   $schema->source($b)->relationships)
    } $schema->sources;

foreach my $source_name ($schema->sources) {
    my $source = $schema->source( $source_name );
    for (1..$opt->number) {
        my $record = {};
        for my $column ($source->columns) {
            my $info = $source->column_info( $column );
            next if $info->{is_auto_increment};
            next if $info->{is_foreign_key}; # for now
            if(      $info->{data_type} eq 'text' ) {
                $record->{$column} = join ' ', rand_words( size => 10 );
            } elsif( $info->{data_type} eq 'integer' ) {
                $record->{$column} = int(rand(1024));
            } elsif( $info->{data_type} eq 'float' ) {
                $record->{$column} = rand;
            } elsif( $info->{data_type} eq 'date' ) {
                $record->{$column} = rand_date();
            } elsif( !$info->{is_nullable} ) {
                warn "column '$column' is not nullable and cannot be " .
                     "generated, skipping\n";
            }
        }
        for my $fk_name ($source->relationships) {
            my $fk = $source->relationship_info( $fk_name );
            next if !$fk->{attrs}{is_depends_on};
            my( $foreign_column ) = sort keys %{$fk->{cond}};
            my $self_column = $fk->{cond}{$foreign_column};
            $foreign_column =~ s/^foreign\.//;
            $self_column =~ s/^self\.//;
            my @all = $schema->resultset($fk->{source})->all;
            $record->{$self_column} = $all[rand(@all)]->get_column( $foreign_column );
        }
        $schema->resultset($source_name)->create( $record );
    }
}

package My::Schema;
use base qw/DBIx::Class::Schema::Loader/;

1;
