/* 
 * © 2007-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */
#ifndef _DB_OBJECT_MATCH_H_
#define _DB_OBJECT_MATCH_H_


#include "grtpp_util.h"
#include "wbpublic_public_interface.h"

#include "grt/common.h"
#include "grtdb/charset_utils.h"
#include "grtsqlparser/sql_facade.h"
#include "db_object_helpers.h"

namespace grt
{

struct WBPUBLICBACKEND_PUBLIC_FUNC DbObjectMatchAlterOmf : public Omf
{
  virtual bool less(const ValueRef& , const ValueRef&) const;
  virtual bool equal(const ValueRef& , const ValueRef&) const;
};

struct WBPUBLICBACKEND_PUBLIC_FUNC DbObjectMatchRecreateOmf : public Omf
{
  virtual bool less(const ValueRef& , const ValueRef&) const;
  virtual bool equal(const ValueRef& , const ValueRef&) const;
};

  template <typename Tgrt>
  class NormalizedComparer
    {
    protected:
      Tgrt _grt;
    public:
      NormalizedComparer(Tgrt grt):_grt(grt){};
      bool normalizedComparison(const ValueRef obj1, const ValueRef obj2, const std::string name)const
      {
        if ((name == "characterSetName") || (name == "collationName"))
        {
          std::string sql1= ObjectRef::cast_from(obj1).get_string_member(name);
          std::string sql2= ObjectRef::cast_from(obj2).get_string_member(name);
          return sql1.empty() || sql2.empty();
        }
        if (name == "foreignKeys"){
          grt::StringRef ename = db_mysql_TableRef::cast_from(obj1)->tableEngine();
          db_mysql_StorageEngineRef engine = bec::TableHelper::get_engine_by_name(_grt, ename);
         if (!engine->supportsForeignKeys())
           return true;
         ename = db_mysql_TableRef::cast_from(obj1)->tableEngine();
         engine = bec::TableHelper::get_engine_by_name(_grt, ename);
         return !engine->supportsForeignKeys();
        }

        if (name == "deleteRule")
        {
          std::string sql1= ObjectRef::cast_from(obj1).get_string_member(name);
          std::string sql2= ObjectRef::cast_from(obj2).get_string_member(name);
          sql1 = toupper(sql1);
          sql2 = toupper(sql2);
          if (sql1 == "RESTRICT")
            sql1 = "";
          if (sql2 == "RESTRICT")
            sql2 = "";
          return sql1 == sql2;
        }
        
        if((name == "comment"))
        {
          std::string sql1= ObjectRef::cast_from(obj1).get_string_member(name);
          std::string sql2= ObjectRef::cast_from(obj2).get_string_member(name);
          return bec::escape_sql_string(sql1) == bec::escape_sql_string(sql2);
        }
        if(name == "sqlDefinition")
        {
        std::string sql1= ObjectRef::cast_from(obj1).get_string_member(name);
        std::string sql2= ObjectRef::cast_from(obj2).get_string_member(name);
        SqlFacade* parser = SqlFacade::instance_for_rdbms_name(_grt, "Mysql");
        
        if (!parser)
          return false;
        
        sql1= parser->normalizeSqlStatement(sql1, GrtNamedObjectRef::cast_from(obj1)->owner()->name());
        sql2= parser->normalizeSqlStatement(sql2, GrtNamedObjectRef::cast_from(obj2)->owner()->name());
        sql1 = toupper(sql1);
        sql2 = toupper(sql2);
//        if (sql1 != sql2)
//          std::cout<<sql1<<std::endl<<std::endl<<sql2;
        return sql1 == sql2;
        }
        return false; 
      };
      operator TSlotNormilizerSlot(){return sigc::mem_fun(*this, &NormalizedComparer<Tgrt>::normalizedComparison);};
    };
  
  
} // namespace grt

#endif // _DB_OBJECT_MATCH_H_
