/* ====================================================================
 * 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.
 * ====================================================================
 */

// test runner
#include "TestRepository.h"

// sc
#include <svn/Client.h>
#include <svn/ClientContext.h>
#include <svn/CommitBaton.h>
#include <svn/CommitInfo.h>
#include <svn/Revision.h>

// svn
#include <svn_repos.h>

// sys
#include <cassert>

/*
xxx
xxx/<name>
xxx/<name>/repos
xxx/<name>/wc
*/

static const sc::String RootPath("tests/");
static const sc::String GreekTree("tests/greek-tree");

class TestRepository::Commit : public svn::CommitBaton
{
public:
  Commit( const sc::String& logMsg )
    : _logMsg(logMsg)
  {
  }

  // svn::CommitBaton
  bool getLogMsg( sc::String& logMsg, sc::String& tmpFile, const svn::CommitItems& items )
  {
    logMsg = _logMsg;
    return true;
  }
  
private:
  sc::String _logMsg;  
};



TestRepository::TestRepository( const sc::String& name )
: _name(name), _base(RootPath)
{
  _base += _name;

  sc::String reposPath(_base);
  reposPath += "/repos";
  _repos = reposPath;

  sc::String wcPath(_base);
  wcPath += "/wc";
  _wc = wcPath;

  char* path = NULL;
  apr_status_t status = apr_filepath_get( &path, 0, _pool );
  assert( status == APR_SUCCESS );
  _cd = sc::String(path);

  _reposUrl = "file://";
#ifdef _WIN32
  _reposUrl += "/";
#endif // _WIN32
  _reposUrl += _cd;
  _reposUrl += "/";
  _reposUrl += _repos;

  _wcPath = _cd;
  _wcPath += "/";
  _wcPath += _wc; 

  cleanup();
}

void TestRepository::setup()
{
  createTestDir();
  createRepository();
  createWorkingCopy();
}

void TestRepository::cleanup()
{
  removeTestDir();
}

void TestRepository::createTestDir()
{
  svn_error_t* err = svn_io_make_dir_recursively( _base, _pool );
  assert( err == SVN_NO_ERROR );
}

void TestRepository::createRepository()
{
  svn_repos_t* repos;
  svn_error_t* err = svn_repos_create( &repos, _repos, NULL, NULL, NULL, NULL, _pool );
  assert( err == SVN_NO_ERROR );

  svn::Client* client = new svn::Client( 
    new svn::ClientContext( NULL, NULL, NULL,
      new Commit(sc::String("imported greek tree.")), sc::NullString, sc::NullString) );

  svn::CommitInfo info;
  sc::Error* scerr = client->import( info, GreekTree, _reposUrl, true );

  delete client;
}

void TestRepository::createWorkingCopy()
{
  svn::Client* client = new svn::Client( 
    new svn::ClientContext( NULL, NULL, NULL, NULL, sc::NullString, sc::NullString) );

  svn::Revnumber revRes;
  sc::Error* scerr = client->checkout(
    &revRes, _reposUrl, _wcPath, svn::RevUnspecified, svn::RevHead, true );

  delete client;
}

void TestRepository::removeTestDir()
{
  sc::String basePath(RootPath);
  basePath += _name;

  svn_error_t* err = svn_io_remove_dir( basePath, _pool );
  svn_error_clear(err);
}

const sc::String& TestRepository::getWcPath() const
{
  return _wcPath;
}
