/* 
 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; version 2 of the
 * License.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301  USA
 */

#include "tut_stdafx.h"

#include "wb_helpers.h"
#include "grtdb/db_object_helpers.h"
#include "grt_test_utility.h"
#include "grtpp_util.h"
#include "base/string_utilities.h"


using namespace base;
using namespace wb;

BEGIN_TEST_DATA_CLASS(wb_copy_paste)

END_TEST_DATA_CLASS;



TEST_MODULE(wb_copy_paste, "copy/paste related tests");


static bool match_member(const grt::MetaClass::Member *member, const grt::ObjectRef &copy, const grt::ObjectRef &source)
{
  if (!grt::is_simple_type(member->type.base.type))
    return true;

  grt::ValueRef value1;
  grt::ValueRef value2;

  value1= source.get_member(member->name);
  value2= copy.get_member(member->name);

  ensure_equals(member->name, value1.repr(), value2.repr());
  
  return true;
}


static void ensure_simple_contents_match(const grt::ObjectRef &copy, const grt::ObjectRef &source)
{
  grt::MetaClass *mc= copy.get_metaclass();
  
  mc->foreach_member(boost::bind(&match_member, _1, copy, source));
}


static void ensure_list_contents_copy(const grt::BaseListRef &copy, const grt::BaseListRef &source)
{
  ensure("table columns list are not same", copy.valueptr() != source.valueptr());

  ensure_equals("list size", copy.count(), source.count());

  for (size_t c= copy.count(), i= 0; i < c; i++)
  {
    ensure("list content not same", copy[i].valueptr() != source[i].valueptr());

    ObjectRef copyRef= ObjectRef::cast_from(copy[i]);
    ObjectRef sourceRef= ObjectRef::cast_from(source[i]);
    ensure_simple_contents_match(grt::ObjectRef(copyRef), grt::ObjectRef(sourceRef));
  }
}


TEST_FUNCTION(1)
{
  WBTester wb;

  wb.wb->open_document("data/workbench/all_objects.mwb");

  ensure_equals("figure count", wb.get_pview()->figures().count(), 6U);

  workbench_physical_TableFigureRef source, copy;
  source= workbench_physical_TableFigureRef::cast_from(grt::find_named_object_in_list(wb.get_pview()->figures(), "table1"));

  ensure("table1", source.is_valid());

  WBComponent *compo= wb.wb->get_component_handling(source);
  ensure("table is copiable", compo!=0);

  grt::CopyContext context(wb.grt);
  copy= workbench_physical_TableFigureRef::cast_from(compo->clone_object(source, wb.get_pview()->rootLayer(), 
    context, false));

  ensure("copy is valid", copy.is_valid());

  ensure("both in same view", copy->owner() == source->owner());
  ensure("both in same layer", copy->layer() == source->layer());

  ensure("copy is not identical", copy.valueptr() != source.valueptr());

  ensure("name is not same", copy->table()->name() != source->table()->name());

  ensure("table is not same", copy->table() != source->table());
  
  ensure_list_contents_copy(copy->table()->columns(), source->table()->columns());

  ensure_list_contents_copy(copy->table()->indices(), source->table()->indices());
}


TEST_FUNCTION(2)
{
  // create a table with PK and make sure that a copy will contain 
  // proper refs to the copied objects

  WBTester wb;
  wb.create_new_document();

  db_mysql_TableRef table;

  table= db_mysql_TableRef(wb.grt);
  table->name("person");
  
  for (int i= 0; i < 5; i++)
  {
    db_mysql_ColumnRef column(wb.grt);

    column->owner(table);
    column->name(strfmt("col%i", i));
    if (i > 2)
      column->setParseType("VARCHAR(32)", wb.get_rdbms()->simpleDatatypes());
    else
      column->setParseType("INT", wb.get_rdbms()->simpleDatatypes());
    table->columns().insert(column);

    if (i == 0)
      table->addPrimaryKeyColumn(column);
  }

  db_mysql_TableRef copy= db_mysql_TableRef::cast_from(grt::copy_object(wb.grt, table));

  ensure("copy", copy.is_valid());
  ensure("copy != orig", copy.valueptr() != table.valueptr());

  ensure_list_contents_copy(table->columns(), copy->columns());

  ensure("pk exists", copy->primaryKey().is_valid());
  ensure("primary key copied", copy->primaryKey().valueptr() != table->primaryKey().valueptr());
  ensure("pk copy points to column copy",
    copy->primaryKey()->columns()[0].valueptr() != table->primaryKey()->columns()[0].valueptr());
  ensure("pk points to correct index", 
    copy->indices().get(0).valueptr() == copy->primaryKey().valueptr());

  ensure_equals("column0", *copy->columns().get(0)->name(), "col0");
  ensure("column owner", copy->columns().get(0)->owner() == copy);

  ensure_equals("pk correct", copy->columns().get(0).valueptr(), copy->primaryKey()->columns().get(0)->referencedColumn().valueptr());
}


END_TESTS

  
  
  
