### ----------------------------------------------------
### -- UpRooted
### -- Licenses: Artistic-2.0
### -- Authors: Paweł bbkr Pabian
### -- File: t/30-reader.rakutest
### ----------------------------------------------------
use lib 'lib';

use Test;

use UpRooted::Schema;
use UpRooted::Table;
use UpRooted::Column;
use UpRooted::Relation;
use UpRooted::Tree;
use UpRooted::Reader;

plan 2;

class UpRooted::Reader::Dummy does UpRooted::Reader {

    # emulate returning dummy rows from each leaf UpRooted::Table
    method !read-path ( $path, %conditions ) {
        
        my $table = $path.leaf-table;
        
        # emulate root UpRooted::Column matching conditions, otherwise return whatever
        my @row = $path.leaf-table.columns.map: { %conditions{ .name } // '*' };
        
        # emulate more rows as UpRooted::Relations chain gets longer
        state $calls = 0;
        take @row for ^(++$calls);
    }
}

subtest 'No implementation' => {
    
    plan 1;
    
    my $schema = UpRooted::Schema.new( name => 's1' );
    my $tree = UpRooted::Tree.new( root-table => UpRooted::Table.new( :$schema, name => 't1' ) );
    
    dies-ok { gather UpRooted::Reader.new( :$tree ).read( ) }, 'UpRooted::Reader must have implementation';

};

subtest 'UpRooted::Tree paths' => {
    
    plan 10;
    
    my $schema = UpRooted::Schema.new( name => 's1' );
    UpRooted::Table.new( :$schema, name => 't1' );
    UpRooted::Table.new( :$schema, name => 't2' );
    UpRooted::Table.new( :$schema, name => 't3' );
    UpRooted::Column.new( table => $schema.table( 't1' ), name => 'c1', :!is-nullable );
    UpRooted::Column.new( table => $schema.table( 't2' ), name => 'c2', :!is-nullable );
    UpRooted::Column.new( table => $schema.table( 't3' ), name => 'c3', :!is-nullable );
    UpRooted::Column.new( table => $schema.table( 't3' ), name => 'c4', :!is-nullable );
    UpRooted::Relation.new(
        parent-columns => $schema.table( 't1' ).columns( 'c1' ),
        child-columns => $schema.table( 't2' ).columns( 'c2' ),
        name => 'r1'
    );
    UpRooted::Relation.new(
        parent-columns => $schema.table( 't2' ).columns( 'c2' ),
        child-columns => $schema.table( 't3' ).columns( 'c3' ),
        name => 'r2'
    );
    my $tree = UpRooted::Tree.new( root-table => $schema.table( 't1' ) );
    my $reader = UpRooted::Reader::Dummy.new( :$tree );
    
    throws-like {
        gather $reader.read( x1 => 1 );
    }, Exception, message => 'UpRooted::Column x1 is not present in UpRooted::Table t1.', 'UpRooted::Columns from conditions must be present in root UpRooted::Table';
    
    my @data = gather $reader.read( c1 => 1 );
    
    is @data.shift, $schema.table( 't1' ), 'Root UpRooted::Table';
    is-deeply @data.shift, [ 1 ], 'Row data';
    
    is @data.shift, $schema.table( 't2' ), 'Leaf UpRooted::Table';
    is-deeply @data.shift, [ '*' ], 'Row data' for ^2;
    
    is @data.shift, $schema.table( 't3' ), 'Leaf UpRooted::Table';
    is-deeply @data.shift, [ '*', '*' ], 'Row data' for ^3;
    
};


