#include <iostream>
#include <string>

#include <boost/test/unit_test.hpp>

#include <zypp-core/base/LogTools.h>
#include <zypp-core/Pathname.h>

using boost::unit_test::test_suite;
using boost::unit_test::test_case;

using namespace zypp;

BOOST_AUTO_TEST_CASE(pathname_default_ctor)
{
  Pathname p;

  BOOST_CHECK_EQUAL(p.empty(),		true );
  BOOST_CHECK_EQUAL(p.absolute(),	false );
  BOOST_CHECK_EQUAL(p.relative(),	false );
  BOOST_CHECK_EQUAL(p.dirname(),	"" );
  BOOST_CHECK_EQUAL(p.basename(),	"" );
  BOOST_CHECK_EQUAL(p.extension(),	"" );
  BOOST_CHECK_EQUAL(p.absolutename(),	"" );
  BOOST_CHECK_EQUAL(p.relativename(),	"" );
}

BOOST_AUTO_TEST_CASE(pathname_root)
{
  Pathname p("/");

  BOOST_CHECK_EQUAL(p.empty(),		false );
  BOOST_CHECK_EQUAL(p.absolute(),	true );
  BOOST_CHECK_EQUAL(p.relative(),	false );
  BOOST_CHECK_EQUAL(p.dirname(),	"/" );
  BOOST_CHECK_EQUAL(p.basename(),	"/" );
  BOOST_CHECK_EQUAL(p.extension(),	"" );
  BOOST_CHECK_EQUAL(p.absolutename(),	"/" );
  BOOST_CHECK_EQUAL(p.relativename(),	"./" );
}

BOOST_AUTO_TEST_CASE(pathname_this)
{
  Pathname p(".");

  BOOST_CHECK_EQUAL(p.empty(),		false );
  BOOST_CHECK_EQUAL(p.absolute(),	false );
  BOOST_CHECK_EQUAL(p.relative(),	true );
  BOOST_CHECK_EQUAL(p.dirname(),	"." );
  BOOST_CHECK_EQUAL(p.basename(),	"." );
  BOOST_CHECK_EQUAL(p.extension(),	"" );
  BOOST_CHECK_EQUAL(p.absolutename(),	"/" );
  BOOST_CHECK_EQUAL(p.relativename(),	"." );
}

BOOST_AUTO_TEST_CASE(pathname_up)
{
  Pathname p("..");

  BOOST_CHECK_EQUAL(p.empty(),		false );
  BOOST_CHECK_EQUAL(p.absolute(),	false );
  BOOST_CHECK_EQUAL(p.relative(),	true );
  BOOST_CHECK_EQUAL(p.dirname(),	"." );
  BOOST_CHECK_EQUAL(p.basename(),	".." );
  BOOST_CHECK_EQUAL(p.extension(),	"" );
  BOOST_CHECK_EQUAL(p.absolutename(),	"/" );
  BOOST_CHECK_EQUAL(p.relativename(),	".." );
}

BOOST_AUTO_TEST_CASE(pathname_abs)
{
  Pathname p("/foo/baa.ka");

  BOOST_CHECK_EQUAL(p.empty(),		false );
  BOOST_CHECK_EQUAL(p.absolute(),	true );
  BOOST_CHECK_EQUAL(p.relative(),	false );
  BOOST_CHECK_EQUAL(p.dirname(),	"/foo" );
  BOOST_CHECK_EQUAL(p.basename(),	"baa.ka" );
  BOOST_CHECK_EQUAL(p.extension(),	".ka" );
  BOOST_CHECK_EQUAL(p.absolutename(),	"/foo/baa.ka" );
  BOOST_CHECK_EQUAL(p.relativename(),	"./foo/baa.ka" );
}

BOOST_AUTO_TEST_CASE(pathname_rel)
{
  Pathname p("./foo/./../baa.ka");

  BOOST_CHECK_EQUAL(p.empty(),		false );
  BOOST_CHECK_EQUAL(p.absolute(),	false );
  BOOST_CHECK_EQUAL(p.relative(),	true );
  BOOST_CHECK_EQUAL(p.dirname(),	"." );
  BOOST_CHECK_EQUAL(p.basename(),	"baa.ka" );
  BOOST_CHECK_EQUAL(p.extension(),	".ka" );
  BOOST_CHECK_EQUAL(p.absolutename(),	"/baa.ka" );
  BOOST_CHECK_EQUAL(p.relativename(),	"./baa.ka" );
}

BOOST_AUTO_TEST_CASE(pathname_relup)
{
  Pathname p("./../foo/./../baa");

  BOOST_CHECK_EQUAL(p.empty(),		false );
  BOOST_CHECK_EQUAL(p.absolute(),	false );
  BOOST_CHECK_EQUAL(p.relative(),	true );
  BOOST_CHECK_EQUAL(p.dirname(),	".." );
  BOOST_CHECK_EQUAL(p.basename(),	"baa" );
  BOOST_CHECK_EQUAL(p.extension(),	"" );
  BOOST_CHECK_EQUAL(p.absolutename(),	"/baa" );
  BOOST_CHECK_EQUAL(p.relativename(),	"../baa" );
}

BOOST_AUTO_TEST_CASE(pathname_strval)
{
  BOOST_CHECK_EQUAL(Pathname("").asString(),		"" );
  BOOST_CHECK_EQUAL(Pathname("/////./").asString(),	"/" );
  BOOST_CHECK_EQUAL(Pathname("./").asString(),		"." );
  BOOST_CHECK_EQUAL(Pathname("/.").asString(),		"/" );
  BOOST_CHECK_EQUAL(Pathname("./..").asString(),	"./.." );	// ? ..
  BOOST_CHECK_EQUAL(Pathname("../").asString(),		"./.." );	// ? ..
  BOOST_CHECK_EQUAL(Pathname(".././..").asString(),	"./../.." );	// ? ../..


  BOOST_CHECK_EQUAL(Pathname("//baa").asString(),	"/baa" );
  BOOST_CHECK_EQUAL(Pathname("/./baa").asString(),	"/baa" );
  BOOST_CHECK_EQUAL(Pathname("/baa/..").asString(),	"/" );
  BOOST_CHECK_EQUAL(Pathname("/baa/../baa").asString(),	"/baa" );
  BOOST_CHECK_EQUAL(Pathname("/./../foo/./../baa").asString(),	"/baa" );

  BOOST_CHECK_EQUAL(Pathname("/").asString(),		"/" );
  BOOST_CHECK_EQUAL(Pathname(".").asString(),		"." );
  BOOST_CHECK_EQUAL(Pathname("..").asString(),		"./.." );
  BOOST_CHECK_EQUAL(Pathname("/.").asString(),		"/" );
  BOOST_CHECK_EQUAL(Pathname("/..").asString(),		"/" );
  BOOST_CHECK_EQUAL(Pathname("/./.").asString(),	"/" );
  BOOST_CHECK_EQUAL(Pathname("/./..").asString(),	"/" );
  BOOST_CHECK_EQUAL(Pathname("/../.").asString(),	"/" );
  BOOST_CHECK_EQUAL(Pathname("/../..").asString(),	"/" );
  BOOST_CHECK_EQUAL(Pathname("/././").asString(),	"/" );
  BOOST_CHECK_EQUAL(Pathname("/./../").asString(),	"/" );
  BOOST_CHECK_EQUAL(Pathname("/.././").asString(),	"/" );
  BOOST_CHECK_EQUAL(Pathname("/../../").asString(),	"/" );

  BOOST_CHECK_EQUAL(Pathname("a\\b").asString(),	"./a\\b" );
  BOOST_CHECK_EQUAL(Pathname("a/b").asString(),		"./a/b" );
  BOOST_CHECK_EQUAL(Pathname("c:a\\b").asString(),	"./c:a\\b" );
  BOOST_CHECK_EQUAL(Pathname("c:a/b").asString(),	"./c:a/b" );
  BOOST_CHECK_EQUAL(Pathname("cc:a\\b").asString(),	"./cc:a\\b" );
  BOOST_CHECK_EQUAL(Pathname("cc:a/b").asString(),	"./cc:a/b" );
}

BOOST_AUTO_TEST_CASE(pathname_stripprefix)
{
  BOOST_CHECK_EQUAL( Pathname::stripprefix( "",		"" ),		"" );
  BOOST_CHECK_EQUAL( Pathname::stripprefix( "",		"/" ),		"/" );
  BOOST_CHECK_EQUAL( Pathname::stripprefix( "",		"/foo" ),	"/foo" );
  BOOST_CHECK_EQUAL( Pathname::stripprefix( "/",	"" ),		"" );
  BOOST_CHECK_EQUAL( Pathname::stripprefix( "/",	"/" ),		"/" );
  BOOST_CHECK_EQUAL( Pathname::stripprefix( "/",	"/foo" ),	"/foo" );
  BOOST_CHECK_EQUAL( Pathname::stripprefix( "/f",	"" ),		"" );
  BOOST_CHECK_EQUAL( Pathname::stripprefix( "/f",	"/" ),		"/" );
  BOOST_CHECK_EQUAL( Pathname::stripprefix( "/f",	"/foo" ),	"/foo" );
  BOOST_CHECK_EQUAL( Pathname::stripprefix( "/foo",	"" ),		"" );
  BOOST_CHECK_EQUAL( Pathname::stripprefix( "/foo",	"/" ),		"/" );
  BOOST_CHECK_EQUAL( Pathname::stripprefix( "/foo",	"/foo" ),	"/" );
  BOOST_CHECK_EQUAL( Pathname::stripprefix( "/foo",	"/foo/baa" ),	"/baa" );
  BOOST_CHECK_EQUAL( Pathname::stripprefix( "/foo",	"/foobaa" ),	"/foobaa" );
}

BOOST_AUTO_TEST_CASE(pathname_assertprefix)
{
  BOOST_CHECK_EQUAL( Pathname::assertprefix( "",	"/a" ),		"/a" );
  BOOST_CHECK_EQUAL( Pathname::assertprefix( "",	"a" ),		"a" );
  BOOST_CHECK_EQUAL( Pathname::assertprefix( "",	"../a" ),	"../a" );

  BOOST_CHECK_EQUAL( Pathname::assertprefix( ".",	"/a" ),		"./a" );
  BOOST_CHECK_EQUAL( Pathname::assertprefix( ".",	"a" ),		"./a" );
  BOOST_CHECK_EQUAL( Pathname::assertprefix( ".",	"../a" ),	"./a" );

  BOOST_CHECK_EQUAL( Pathname::assertprefix( "..",	"/a" ),		"../a" );
  BOOST_CHECK_EQUAL( Pathname::assertprefix( "..",	"a" ),		"../a" );
  BOOST_CHECK_EQUAL( Pathname::assertprefix( "..",	"../a" ),	"../a" );

  BOOST_CHECK_EQUAL( Pathname::assertprefix( "a",	"/a" ),		"a/a" );
  BOOST_CHECK_EQUAL( Pathname::assertprefix( "a",	"a" ),		"a" );
  BOOST_CHECK_EQUAL( Pathname::assertprefix( "a",	"../a" ),	"a/a" );

  BOOST_CHECK_EQUAL( Pathname::assertprefix( "../a",	"/a" ),		"../a/a" );
  BOOST_CHECK_EQUAL( Pathname::assertprefix( "../a",	"a" ),		"../a/a" );
  BOOST_CHECK_EQUAL( Pathname::assertprefix( "../a",	"../a" ),	"../a" );

  BOOST_CHECK_EQUAL( Pathname::assertprefix( "/",	"/a" ),		"/a" );
  BOOST_CHECK_EQUAL( Pathname::assertprefix( "/",	"a" ),		"/a" );
  BOOST_CHECK_EQUAL( Pathname::assertprefix( "/",	"../a" ),	"/a" );

  BOOST_CHECK_EQUAL( Pathname::assertprefix( "/root",	"/a" ),		"/root/a" );
  BOOST_CHECK_EQUAL( Pathname::assertprefix( "/root",	"a" ),		"/root/a" );
  BOOST_CHECK_EQUAL( Pathname::assertprefix( "/root",	"../a" ),	"/root/a" );

  BOOST_CHECK_EQUAL( Pathname::assertprefix( "/root",	"/root/a" ),	"/root/a" );
  BOOST_CHECK_EQUAL( Pathname::assertprefix( "/root",	"root/a" ),	"/root/root/a" );
  BOOST_CHECK_EQUAL( Pathname::assertprefix( "/root",	"../root/a" ),	"/root/root/a" );
  BOOST_CHECK_EQUAL( Pathname::assertprefix( "/root",	"/roota" ),	"/root/roota" );
}
