/* ====================================================================
 * Copyright (c) 2008       Martin Hauner
 *                          http://subcommander.tigris.org
 *
 * Subcommander is licensed as described in the file doc/COPYING, which
 * you should have received as part of this distribution.
 * ====================================================================
 */

#include "MoveTest.h"

// cppunit
#include <cppunit/TestSuite.h>
#include <cppunit/TestCaller.h>

// sc
#include "TestRepository.h"
#include "svn/Client.h"
#include "svn/ClientContext.h"
#include "svn/CommitInfo.h"
#include "svn/StatusBaton.h"
#include "svn/Revision.h"
#include "svn/WcStatus.h"
#include "util/Error.h"
#include "util-test/AssertionTraitString.h"


class MoveTest::StatusBaton : public svn::StatusBaton
{
public:
  virtual void status( const char* path, svn::WcStatusPtr status )
  {
    _statuss.push_back(status);
  }

  int size()
  {
    return (int)_statuss.size();
  }

  svn::WcStatusKind status( int idx )
  {
    assert( idx >= 0 );
    assert( idx < (int)_statuss.size() );

    return _statuss[idx]->getTextStatus();
  }

  const sc::String& name( int idx )
  {
    assert( idx >= 0 );
    assert( idx < (int)_statuss.size() );

    return _statuss[idx]->getName();
  }

private:
  svn::WcStatuss _statuss;
};


#define CPPUNIT_ASSERT_ERROR( actual ) \
{\
  CPPUNIT_ASSERT_EQUAL( sc::Success, actual ); \
  delete actual;\
}


void MoveTest::setUp()
{
  _test = new TestRepository( sc::String("MoveTest") );
  _test->setup();

  svn::ClientContext* ctx = new svn::ClientContext( NULL, NULL, NULL, NULL,
    sc::NullString, sc::NullString );

  _client = new svn::Client( ctx, NULL );
}

void MoveTest::tearDown()
{
  delete _client;

  _test->cleanup();
  delete _test;
}

void MoveTest::move()
{
  sc::Error* err;
    
  svn::CommitInfo info;
  svn::Paths src;
  src.push_back( path("/A/B/E/alpha") );
  src.push_back( path("/A/B/E/beta") );
  svn::Paths dst;
  dst.push_back( path("/A/B/F/alpha") );
  dst.push_back( path("/A/B/F/beta") );

  err = _client->move( info, src, dst, false );
  CPPUNIT_ASSERT_ERROR(err);

  svn::Revnumber rev;
  StatusBaton baton;
  err = _client->status( &rev, _test->getWcPath(), svn::RevUnspecified,
    &baton, true, false, false, false );

  CPPUNIT_ASSERT_ERROR( err );
  CPPUNIT_ASSERT_EQUAL( 4, baton.size() );
  CPPUNIT_ASSERT_EQUAL( path("/A/B/E/alpha"),  baton.name(0) );
  CPPUNIT_ASSERT_EQUAL( path("/A/B/E/beta"),   baton.name(1) );
  CPPUNIT_ASSERT_EQUAL( path("/A/B/F/alpha"),  baton.name(2) );
  CPPUNIT_ASSERT_EQUAL( path("/A/B/F/beta"),   baton.name(3) );
  CPPUNIT_ASSERT_EQUAL( svn::WcStatus_Deleted, baton.status(0) );
  CPPUNIT_ASSERT_EQUAL( svn::WcStatus_Deleted, baton.status(1) );
  CPPUNIT_ASSERT_EQUAL( svn::WcStatus_Added,   baton.status(2) );
  CPPUNIT_ASSERT_EQUAL( svn::WcStatus_Added,   baton.status(3) );
}

const sc::String MoveTest::path(const char* path)
{
  return _test->getWcPath() + sc::String(path);
}
