#include "../bdm/stat/exp_family.h"
#include "../mat_checks.h"
#include "UnitTest++.h"

using namespace bdm;

TEST ( datalink_test ) {
    // RV names are global, and a, b and c are already taken by a
    // different test...
    RV a = RV ( "{dla }", "2" );
    RV b = RV ( "{dlb }" );
    RV c = RV ( "{dlc }" );

    RV ab = a;
    ab.add ( b );

    RV abc = ab;
    abc.add ( c );

    datalink dl ( ab, abc );
    vec total ( "0 37 42 66" );
    vec filtered = dl.pushdown ( total );
    int exp_f[] = { 0, 37, 42 };
    int exp_sz = sizeof ( exp_f ) / sizeof ( exp_f[0] );
    CHECK_EQUAL ( exp_sz, filtered.size() );
    for ( int i = 0; i < exp_sz; ++i ) {
        CHECK_EQUAL ( exp_f[i], filtered ( i ) );
    }

    datalink unnamed;
    unnamed.set_connection ( 1, 2, ivec ( "0" ) );
    filtered = unnamed.pushdown ( vec ( "37 42" ) );
    CHECK_EQUAL ( vec ( "37" ), filtered );
}

TEST ( datalink_m2e_test ) {
    RV a = RV ( "{dla }", "2" );
    RV b = RV ( "{dlb }" );
    RV c = RV ( "{dlc }" );

    RV ab = a;
    ab.add ( b );

    RV ba = a;
    ba.add ( b );

    RV abc = ab;
    abc.add ( c );

    datalink_m2e dl;
    dl.set_connection ( ba, c, abc );
    vec total ( "0 37 42 66" );
    vec cond = dl.get_cond ( total );
    CHECK_EQUAL ( 1, cond.size() );
    CHECK_EQUAL ( 66, cond ( 0 ) );

    vec big ( 4 );
    dl.pushup_cond ( big, vec ( "2 3 5" ), vec ( "7" ) );
    CHECK_EQUAL ( vec ( "2 3 5 7" ), big );
}

TEST ( datalink_m2m_test ) {
    RV a = RV ( "{dla }", "2" );
    RV b = RV ( "{dlb }" );
    RV c = RV ( "{dlc }" );

    datalink_m2m dl;
    dl.set_connection ( a, concat ( b, c ), concat ( a, b ), c );

    vec val ( "1 1.5 2" );
    vec cond ( "3" );

    vec p = dl.pushdown ( val );
    double exp_p[] = { 1.0, 1.5 };
    int exp_sz = sizeof ( exp_p ) / sizeof ( exp_p[0] );
    CHECK_EQUAL ( exp_sz, p.size() );
    for ( int i = 0; i < exp_sz; ++i ) {
        CHECK_EQUAL ( exp_p[i], p ( i ) );
    }

    vec dlcond = dl.get_cond ( val, cond );
    int exp_c[] = { 2, 3 };
    exp_sz = sizeof ( exp_c ) / sizeof ( exp_c[0] );
    CHECK_EQUAL ( exp_sz, dlcond.size() );
    for ( int i = 0; i < exp_sz; ++i ) {
        CHECK_EQUAL ( exp_c[i], dlcond ( i ) );
    }
}

TEST ( datalink_buffered_test ) {
    RV a = RV ( "{dl_a }" );
    RV b = RV ( "{dlb }" );
    RV ab = concat ( a, b );
    RV aa = a;
    a.t_plus ( -1 );
    aa.add ( a );


    datalink_buffered dl;
    dl.set_connection ( concat ( aa, b ), ab );

    vec val_up ( "1 2" );
    dl.store_data ( val_up );
    val_up = "3 4";


    vec p = dl.pushdown ( val_up );
    vec exp_p = " 3, 1, 4 ";
    CHECK_EQUAL ( exp_p, p );

}
