#include "stdafx.h"

#include "wb_config.h"

#include "grtui/grt_wizard_plugin.h"
#include "grtui/wizard_view_text_page.h"

#include "db_mysql_diff_reporting.h"

#include "db.mysql/backend/db_plugin_be.h"

using namespace grtui;
using namespace mforms;


#include "diff_source_select_page.h"

#include "db.mysql/frontend/connection_page.h"
#include "db.mysql/frontend/schema_selection_page.h"
#include "db.mysql/frontend/fetch_schema_names_page.h"
#include "db.mysql/frontend/fetch_schema_contents_page.h"

  
class ViewResultPage : public ViewTextPage
{
public:
  ViewResultPage(WizardForm *form)
    : ViewTextPage(form, "viewdiff", (ViewTextPage::Buttons)(ViewTextPage::SaveButton|ViewTextPage::CopyButton), "Text Files (*.txt)|*.txt")
  {
    set_short_title(_("Differences Report"));
    set_title(_("Differences Found in Catalog Comparison"));
  }

  void set_generate_text_slot(const sigc::slot<std::string> &slot)
  {
    _generate= slot;
  }

  virtual void enter(bool advancing)
  {
    if (advancing)
      _text.set_value(_generate());
  }

  virtual bool allow_cancel() { return false; }
  virtual bool next_closes_wizard() { return true; }

protected:  
  sigc::slot<std::string> _generate;
};


//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

class WbPluginDiffReport : public WizardPlugin
{
public:
  WbPluginDiffReport(grt::Module *module)
    : WizardPlugin(module), _be(grtm())
  {
    add_page(_source_page= new SourceSelectPage(this));

    Db_plugin *dbplugin[2];
    _left_db.grtm(grtm());
    _right_db.grtm(grtm());
    
    dbplugin[0]= &_left_db;
    dbplugin[1]= &_right_db;
    
    const char *title_prefix[2];
    title_prefix[0]= _("Left Catalog: ");
    title_prefix[1]= _("Right Catalog: ");

    for (int i= 0; i < 2; i++)
    {
      ConnectionPage *connect;
      add_page(connect= new ConnectionPage(this, strfmt("connect%i", i).c_str()));
      connect->set_db_connection(dbplugin[i]->db_conn());
      connect->set_title(std::string(title_prefix[i]).append(connect->get_title()));

      FetchSchemaNamesProgressPage *fetch_names_page;
      add_page(fetch_names_page= new FetchSchemaNamesProgressPage(this, strfmt("fetchNames%i",i).c_str()));
      fetch_names_page->set_db_connection(dbplugin[i]->db_conn());
      fetch_names_page->set_load_schemata_slot(sigc::bind(sigc::mem_fun(this, &WbPluginDiffReport::load_schemata), dbplugin[i]));
      fetch_names_page->set_title(std::string(title_prefix[i]).append(fetch_names_page->get_title()));

      SchemaSelectionPage *schema_page;
      add_page(schema_page= new SchemaSelectionPage(this, strfmt("pickSchemata%i", i).c_str()));
      schema_page->set_db_plugin(dbplugin[i]);
      schema_page->set_title(std::string(title_prefix[i]).append(schema_page->get_title()));

      FetchSchemaContentsProgressPage *fetch_schema_page;
      add_page(fetch_schema_page= new FetchSchemaContentsProgressPage(this, strfmt("fetchSchema%i",i).c_str()));
      fetch_schema_page->set_db_plugin(dbplugin[i]);
      fetch_schema_page->set_title(std::string(title_prefix[i]).append(fetch_schema_page->get_title()));
    }
    
    ViewResultPage *page;
    add_page(page= new ViewResultPage(this));
    page->set_generate_text_slot(sigc::mem_fun(this, &WbPluginDiffReport::generate_report));

    set_title(_("Compare and Report Differences in Catalogs"));
  }
  

  std::string generate_report()
  {
    db_CatalogRef left_catalog, right_catalog;
    std::string left_file, right_file;

    if (_source_page->get_left_source() == SourceSelectPage::ServerSource)
      left_catalog= _left_db.db_catalog();

    if (_source_page->get_right_source() == SourceSelectPage::ServerSource)
      right_catalog= _right_db.db_catalog();

    left_file= values().get_string("left_source_file");
    right_file= values().get_string("right_source_file");

    return _be.generate_report(left_file, right_file, left_catalog, right_catalog);
  }


  virtual WizardPage *get_next_page(WizardPage *current)
  {
    std::string curid= current->get_id();
    std::string nextid;
    
    if (curid == "source")
    {
      if (_source_page->get_left_source() == SourceSelectPage::ServerSource)
        nextid= "connect0";
      else if (_source_page->get_right_source() == SourceSelectPage::ServerSource)
        nextid= "connect1";
      else
        nextid= "viewdiff";
    }
    else if (curid == "fetchSchema0")
    {
      if (_source_page->get_right_source() == SourceSelectPage::ServerSource)
        nextid= "connect1";
      else
        nextid= "viewdiff";
    }

    if (!nextid.empty())
      return get_page_with_id(nextid);
    else
      return WizardForm::get_next_page(current);
  }


protected:
  DbMySQLDiffReporting _be;
  Db_plugin _left_db;
  Db_plugin _right_db;
  SourceSelectPage *_source_page;
  
  std::vector<std::string> load_schemata(Db_plugin *db)
  {
    std::vector<std::string> names;
    db->load_schemata(names);
    return names;
  }
};


WizardPlugin *createWbPluginDiffReport(grt::Module *module)
{
  return new WbPluginDiffReport(module);
}

