// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "gui/config_dialog/keymap_editor.h"

#include <QtCore/QFile>
#include <QtGui/QFileDialog>
#include <QtGui/QtGui>
#include <algorithm>  // for unique
#include <cctype>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include "base/config_file_stream.h"
#include "base/logging.h"
#include "base/singleton.h"
#include "base/util.h"
#include "gui/base/table_util.h"
#include "gui/config_dialog/combobox_delegate.h"
#include "gui/config_dialog/keybinding_editor_delegate.h"
#include "session/commands.pb.h"
#include "session/internal/keymap.h"
#include "session/key_parser.h"
// TODO(komatsu): internal files should not be used from external modules.

namespace mozc {
namespace gui {
namespace {

config::Config::SessionKeymap kKeyMaps[] = {
  config::Config::ATOK,
  config::Config::MSIME,
  config::Config::KOTOERI,
};

const char *kKeyMapStatus[] = {
  "DirectInput",
  "Precomposition",
  "Composition",
  "Conversion",
  "Suggestion",
  "Prediction",
};

const char kInsertCharacterCommand[] = "InsertCharacter";
const char kDirectMode[] = "DirectInput";
const char kReportBugCommand[] = "ReportBug";
// Old command name
const char kEditInsertCommand[] = "EditInsert";

#if defined(OS_MACOSX)
const char kIMEOnCommand[] = "IMEOn";
const char kIMEOffCommand[] = "IMEOff";
#endif  // OS_MACOSX

enum {
  NEW_INDEX              = 0,
  REMOVE_INDEX           = 1,
  IMPORT_FROM_FILE_INDEX = 2,
  EXPORT_TO_FILE_INDEX   = 3,
  MENU_SIZE              = 4
};

// Keymap validator for deciding that input is configurable
class KeyMapValidator {
 public:
  KeyMapValidator() {
    invisible_commands_.insert(kInsertCharacterCommand);
    invisible_commands_.insert(kReportBugCommand);
    // Old command name.
    invisible_commands_.insert(kEditInsertCommand);
#if defined(OS_MACOSX)
    // On Mac, we cannot customize keybindings for IME ON/OFF
    // So we do not show them.
    // TODO(toshiyuki): remove them after implimenting IME ON/OFF for Mac
    invisible_commands_.insert(kIMEOnCommand);
    invisible_commands_.insert(kIMEOffCommand);
#endif  // OS_MACOSX

    invisible_modifiers_.insert(mozc::commands::KeyEvent::KEY_DOWN);
    invisible_modifiers_.insert(mozc::commands::KeyEvent::KEY_UP);

    invisible_key_events_.insert(mozc::commands::KeyEvent::KANJI);
    invisible_key_events_.insert(mozc::commands::KeyEvent::ON);
    invisible_key_events_.insert(mozc::commands::KeyEvent::OFF);
    invisible_key_events_.insert(mozc::commands::KeyEvent::TEXT_INPUT);
  }

  bool IsVisibleKey(const string &key) {
    mozc::commands::KeyEvent key_event;
    const bool parse_success = mozc::KeyParser::ParseKey(key, &key_event);
    if (!parse_success) {
      VLOG(3) << "key parse failed";
      return false;
    }
    for (size_t i = 0; i < key_event.modifier_keys_size(); ++i) {
      if (invisible_modifiers_.find(key_event.modifier_keys(i))
          != invisible_modifiers_.end()) {
        VLOG(3) << "invisible modifiers: " << key_event.modifier_keys(i);
        return false;
      }
    }
    if (key_event.has_special_key() &&
        (invisible_key_events_.find(key_event.special_key())
         != invisible_key_events_.end())) {
      VLOG(3) << "invisible special key: " << key_event.special_key();
      return false;
    }
    return true;
  }

  bool IsVisibleStatus(const string &status) {
    // no validation for now.
    return true;
  }

  bool IsVisibleCommand(const string &command) {
    if (invisible_commands_.find(command) == invisible_commands_.end()) {
      return true;
    }
    VLOG(3) << "invisible command: " << command;
    return false;
  }

  // Returns true if the key map entry is valid
  // invalid keymaps are not exported/imported.
  bool IsValidEntry(const vector<string> &fields) {
    if (fields.size() < 3) {
      return false;
    }

#ifdef NO_LOGGING
    if (fields[2] == kReportBugCommand) {
      return false;
    }
#endif
    return true;
  }

  // Returns true if the key map entry is configurable and
  // we want to show them.
  bool IsVisibleEntry(const vector<string> &fields) {
    if (fields.size() < 3) {
      return false;
    }
    const string &key = fields[1];
    const string &command = fields[2];
    if (!IsVisibleKey(key)) {
      return false;
    }
    if (!IsVisibleCommand(command)) {
      return false;
    }

    return true;
  }

 private:
  set<uint32> invisible_modifiers_;
  set<uint32> invisible_key_events_;
  set<string> invisible_commands_;
};

class KeyMapTableLoader {
 public:
  KeyMapTableLoader() {
    string line;
    vector<string> fields;
    set<string> status;
    set<string> commands;
    KeyMapValidator *validator = mozc::Singleton<KeyMapValidator>::get();

    // get all command names
    set<string> command_names;
    mozc::keymap::KeyMapManager manager;
    manager.GetAvailableCommandNameDirect(&command_names);
    manager.GetAvailableCommandNamePrecomposition(&command_names);
    manager.GetAvailableCommandNameComposition(&command_names);
    manager.GetAvailableCommandNameConversion(&command_names);
    manager.GetAvailableCommandNameZeroQuerySuggestion(&command_names);
    manager.GetAvailableCommandNameSuggestion(&command_names);
    manager.GetAvailableCommandNamePrediction(&command_names);
    for (set<string>::const_iterator itr = command_names.begin();
         itr != command_names.end(); ++itr) {
      if (validator->IsVisibleCommand(*itr)) {
        commands.insert(*itr);
      }
    }

    for (size_t i = 0; i < arraysize(kKeyMapStatus); ++i) {
      status_ << QString::fromUtf8(kKeyMapStatus[i]);
    }

    for (set<string>::const_iterator it = commands.begin();
         it != commands.end(); ++it) {
      commands_ << QString::fromUtf8(it->c_str());
    }
  }

  const QStringList &status() { return status_; }
  const QStringList &commands() { return commands_; }

 private:
  QStringList status_;
  QStringList commands_;
};
}  // namespace

KeyMapEditorDialog::KeyMapEditorDialog(QWidget *parent)
    : GenericTableEditorDialog(parent, 3),
      status_delegate_(new ComboBoxDelegate),
      commands_delegate_(new ComboBoxDelegate),
      keybinding_delegate_(new KeyBindingEditorDelegate) {
  actions_.reset(new QAction * [MENU_SIZE]);
  import_actions_.reset(new QAction * [arraysize(kKeyMaps)]);

  actions_[NEW_INDEX] =  mutable_edit_menu()->addAction(tr("New entry"));
  actions_[REMOVE_INDEX] =
    mutable_edit_menu()->addAction(tr("Remove selected entries"));
  mutable_edit_menu()->addSeparator();

  QMenu *sub_menu =
               mutable_edit_menu()->addMenu(tr("Import predefined mapping"));
  DCHECK(sub_menu);

  // Make sure that the order should be the same as kKeyMapTableFiles
  import_actions_[0] = sub_menu->addAction(tr("ATOK"));
  import_actions_[1] = sub_menu->addAction(tr("MS-IME"));
  import_actions_[2] = sub_menu->addAction(tr("Kotoeri"));

  mutable_edit_menu()->addSeparator();
  actions_[IMPORT_FROM_FILE_INDEX] =
      mutable_edit_menu()->addAction(tr("Import from file..."));
  actions_[EXPORT_TO_FILE_INDEX] =
      mutable_edit_menu()->addAction(tr("Export to file..."));

  // expand the last "Command" column
  mutable_table_widget()->setColumnWidth
      (0, static_cast<int>(mutable_table_widget()->columnWidth(0) * 1.5));
  mutable_table_widget()->setColumnWidth
      (1, static_cast<int>(mutable_table_widget()->columnWidth(1) * 1.1));
  mutable_table_widget()->horizontalHeader()->setStretchLastSection(true);

  KeyMapTableLoader *loader = Singleton<KeyMapTableLoader>::get();

  // Generate i18n status list
  const QStringList &statuses = loader->status();
  QStringList i18n_statuses;
  for (size_t i = 0; i < statuses.size(); ++i) {
    const QString i18n_status = tr(statuses[i].toStdString().data());
    i18n_statuses.append(i18n_status);
    normalized_status_map_.insert(
        make_pair(i18n_status.toStdString(), statuses[i].toStdString()));
  }
  status_delegate_->SetItemList(i18n_statuses);

  // Generate i18n command list.
  const QStringList &commands = loader->commands();
  QStringList i18n_commands;
  for (size_t i = 0; i < commands.size(); ++i) {
    const QString i18n_command = tr(commands[i].toStdString().data());
    i18n_commands.append(i18n_command);
    normalized_command_map_.insert(
        make_pair(i18n_command.toStdString(), commands[i].toStdString()));
  }
  i18n_commands.sort();
  commands_delegate_->SetItemList(i18n_commands);

  mutable_table_widget()->setItemDelegateForColumn(0,
                                                   status_delegate_.get());
  mutable_table_widget()->setItemDelegateForColumn(1,
                                                   keybinding_delegate_.get());
  mutable_table_widget()->setItemDelegateForColumn(2,
                                                   commands_delegate_.get());

  setWindowTitle(tr("Mozc keymap editor"));
  CHECK(mutable_table_widget());
  CHECK_EQ(mutable_table_widget()->columnCount(), 3);
  QStringList headers;
  headers << tr("Mode") << tr("Key") << tr("Command");
  mutable_table_widget()->setHorizontalHeaderLabels(headers);

  resize(500, 350);

  UpdateMenuStatus();
}

KeyMapEditorDialog::~KeyMapEditorDialog() {}

bool KeyMapEditorDialog::LoadFromStream(istream *is) {
  if (is == NULL) {
    return false;
  }

  string line;
  if (!getline(*is, line)) {   // must have 1st line
    return false;
  }

  vector<string> fields;
  int row = 0;
  mutable_table_widget()->setRowCount(0);
  mutable_table_widget()->verticalHeader()->hide();

  invisible_keymap_table_.clear();
  direct_mode_commands_.clear();
  while (getline(*is, line)) {
    if (line.empty() || line[0] == '#') {
      continue;
    }
    Util::ChopReturns(&line);

    fields.clear();
    Util::SplitStringUsing(line, "\t", &fields);
    if (fields.size() < 3) {
      VLOG(3) << "field size < 3";
      continue;
    }

    const string &status = fields[0];
    const string &key = fields[1];
    const string &command = fields[2];

    // don't accept invalid keymap entries.
    if (!Singleton<KeyMapValidator>::get()->IsValidEntry(fields)) {
      VLOG(3) << "invalid entry.";
      continue;
    }

    // don't show invisible (not configurable) keymap entries.
    if (!Singleton<KeyMapValidator>::get()->IsVisibleEntry(fields)) {
      VLOG(3) << "invalid entry to show. add to invisible_keymap_table_";
      invisible_keymap_table_ += status;
      invisible_keymap_table_ += '\t';
      invisible_keymap_table_ += key;
      invisible_keymap_table_ += '\t';
      invisible_keymap_table_ += command;
      invisible_keymap_table_ += '\n';
      continue;
    }

    if (status == kDirectMode) {
      direct_mode_commands_.insert(key);
    }

    QTableWidgetItem *status_item
        = new QTableWidgetItem(tr(status.c_str()));
    QTableWidgetItem *key_item
        = new QTableWidgetItem(QString::fromUtf8(key.c_str()));
    QTableWidgetItem *command_item
        = new QTableWidgetItem(tr(command.c_str()));

    mutable_table_widget()->insertRow(row);
    mutable_table_widget()->setItem(row, 0, status_item);
    mutable_table_widget()->setItem(row, 1, key_item);
    mutable_table_widget()->setItem(row, 2, command_item);
    ++row;
  }

  UpdateMenuStatus();

  return true;
}

bool KeyMapEditorDialog::Update() {
  if (mutable_table_widget()->rowCount() == 0) {
    QMessageBox::warning(this,
                         windowTitle(),
                         tr("Current keymap table is empty. "
                            "You might want to import a pre-defined "
                            "keymap table first."));
    return false;
  }

  set<string> new_direct_mode_commands;

  KeyMapValidator *validator = Singleton<KeyMapValidator>::get();
  string *keymap_table = mutable_table();

  *keymap_table = "status\tkey\tcommand\n";

  for (int i = 0; i < mutable_table_widget()->rowCount(); ++i) {
    const string &i18n_status =
        TableUtil::SafeGetItemText(mutable_table_widget(), i, 0).toStdString();
    const string &key =
        TableUtil::SafeGetItemText(mutable_table_widget(), i, 1).toStdString();
    const string &i18n_command =
        TableUtil::SafeGetItemText(mutable_table_widget(), i, 2).toStdString();

    const map<string, string>::const_iterator status_it =
        normalized_status_map_.find(i18n_status);
    if (status_it == normalized_status_map_.end()) {
      LOG(ERROR) << "Unsupported i18n status name: " << i18n_status;
      continue;
    }
    const string &status = status_it->second;

    const map<string, string>::const_iterator command_it =
        normalized_command_map_.find(i18n_command);
    if (command_it == normalized_command_map_.end()) {
      LOG(ERROR) << "Unsupported i18n command name:" << i18n_command;
      continue;
    }
    const string &command = command_it->second;

    if (!validator->IsVisibleKey(key)) {
      QMessageBox::warning(this,
                           windowTitle(),
                           (tr("Invalid key:\n%1")
                            .arg(QString::fromUtf8(key.c_str()))));
      return false;
    }
    const string keymap_line = status + "\t" + key + "\t" + command;
    *keymap_table += keymap_line;
    *keymap_table += '\n';

    if (status == kDirectMode) {
      new_direct_mode_commands.insert(key);
    }
  }
  *keymap_table += invisible_keymap_table_;

  if (new_direct_mode_commands != direct_mode_commands_) {
#if defined(OS_WIN) || defined(OS_LINUX)
    QMessageBox::information(
        this,
        windowTitle(),
        tr("Changes of keymaps for direct input mode will apply only to "
           "applications that are launched after making your "
           "modifications."));
#endif  // OS_WIN || OS_LINUX
    direct_mode_commands_ = new_direct_mode_commands;
  }

  return true;
}

void KeyMapEditorDialog::UpdateMenuStatus() {
  const bool status = (mutable_table_widget()->rowCount() > 0);
  actions_[REMOVE_INDEX]->setEnabled(status);
  actions_[EXPORT_TO_FILE_INDEX]->setEnabled(status);
  UpdateOKButton(status);
}

void KeyMapEditorDialog::OnEditMenuAction(QAction *action) {
  int import_index = -1;
  for (size_t i = 0; i < arraysize(kKeyMaps); ++i) {
    if (import_actions_[i] == action) {
      import_index = i;
      break;
    }
  }

  if (action == actions_[NEW_INDEX]) {
    AddNewItem();
  } else if (action == actions_[REMOVE_INDEX]) {
    DeleteSelectedItems();
  } else if (import_index != -1 ||
             action == actions_[IMPORT_FROM_FILE_INDEX]) {
    if (mutable_table_widget()->rowCount() > 0 &&
        QMessageBox::Ok !=
        QMessageBox::question(
            this,
            windowTitle(),
            tr("Do you want to overwrite the current keymaps?"),
            QMessageBox::Ok | QMessageBox::Cancel,
            QMessageBox::Cancel)) {
      return;
    }

    // import_category_index means Import from file
    if (action == actions_[IMPORT_FROM_FILE_INDEX]) {
      Import();
    // otherwise, load from predefined tables
    } else if (import_index >= 0 &&
               import_index < arraysize(kKeyMaps)) {
      const char *keymap_file =
          keymap::KeyMapManager::GetKeyMapFileName(kKeyMaps[import_index]);
      scoped_ptr<istream> ifs(
          ConfigFileStream::LegacyOpen(keymap_file));
      CHECK(ifs.get() != NULL);  // should never happen
      CHECK(LoadFromStream(ifs.get()));
    }
  } else if (action == actions_[EXPORT_TO_FILE_INDEX]) {
    Export();
  }

  return;
}

// static
bool KeyMapEditorDialog::Show(QWidget *parent,
                              const string &current_keymap,
                              string *new_keymap) {
  KeyMapEditorDialog window(parent);
  window.LoadFromString(current_keymap);

  // open modal mode
  const bool result = (QDialog::Accepted == window.exec());
  new_keymap->clear();
  if (result) {
    *new_keymap = window.table();
  }
  return result;
}
}  // namespace gui
}  // namespace mozc
