// -*- C++ -*-
#include <ept/config.h>
#include <ept/core/apt.h>
#include <ept/core/list.h>
#include <ept/test.h>

using namespace ept::core;

struct TestCoreApt : AptTestEnvironment
{
    package::Source pkgs;
    version::Source vers;
    ept::Token t;

    TestCoreApt() : pkgs( db ), vers( db ) {
        t._id = "sp";
    }

    Test token() {
        assert_eq( t.package(), "sp" );
        assert_eq( t.version(), "" );
    }

    Test tokenVersion() {
        ept::Token t2;
        t2._id = "libwibble-dev_0.1.10";
        assert_eq( t2.package(), "libwibble-dev" );
        assert_eq( t2.version(), "0.1.10" );
    }

    Test packageName() {
        assert_eq( t.package(), pkgs.get< package::Name >( t ) );
    }

    template< typename List >
    void checkPackageNameList( List l ) {
        while ( !l.empty() ) {
            assert_eq( l.token().package(), l.property() );
            l = l.tail();
        }
    }

    template< typename List >
    void checkVersionPackageList( List l ) {
        while ( !l.empty() ) {
            assert_eq( l.property().package(), l.token().package() );
            assert_eq( l.property().version(), "" );
            l = l.tail();
        }
    }

    Test packageCount() {
        assert_eq( list::count( pkgs.list< package::Name >() ),
                   3778 );
    }

    Test packageNameList() {
        checkPackageNameList( pkgs.list< package::Name >() );
    }

    Test versionCount() {
        assert_eq( list::count( vers.list< version::Package >() ),
                  1808 );
    }

    Test versionPackage() {
        checkVersionPackageList( vers.list< version::Package >() );
    }

    Test validate() {
        assert_eq( t, db.validate( t ) );
        assert_neq( ept::Token( "libfoobar" ),
                    db.validate( ept::Token( "libfooar" ) ) );
        assert_eq( ept::Token(), db.validate( ept::Token( "libfoobar" ) ) );
    }

    Test packageState() {
        assert( db.packageState( t ) & PackageState::Keep );
    }

    Test packageState2() {
        assert( pkgs.get< package::State >( t ) & PackageState::Keep );
    }

    Test exists() {
        assert( pkgs.exists( t ) );
        assert( !pkgs.exists( ept::Token( "nonexistent-package" ) ) );
    }

    Test invalidate() {
        assert( pkgs.exists( t ) );
        db.invalidate();
        assert( pkgs.exists( t ) );
    }
};
