/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is the Mork Reader.
 *
 * The Initial Developer of the Original Code is
 * Google Inc.
 * Portions created by the Initial Developer are Copyright (C) 2006
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *   Brian Ryner <bryner@brianryner.com> (original author)
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

// Source:
// http://mxr.mozilla.org/firefox/source/db/morkreader/nsMorkReader.cpp
// This file has been converted to google style.

#include "chrome/browser/importer/mork_reader.h"

#include <algorithm>

#include "base/file_path.h"
#include "base/i18n/icu_string_conversions.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "chrome/browser/history/history_types.h"
#include "chrome/browser/importer/firefox_importer_utils.h"
#include "chrome/browser/importer/importer_bridge.h"

namespace {

// Convert a hex character (0-9, A-F) to its corresponding byte value.
// Returns -1 if the character is invalid.
inline int HexCharToInt(char c) {
  if ('0' <= c && c <= '9')
    return c - '0';
  if ('A' <= c && c <= 'F')
    return c - 'A' + 10;
  return -1;
}

// Unescape a Mork value.  Mork uses $xx escaping to encode non-ASCII
// characters.  Additionally, '$' and '\' are backslash-escaped.
// The result of the unescape is in returned.
std::string MorkUnescape(const std::string& input) {
  // We optimize for speed over space here -- size the result buffer to
  // the size of the source, which is an upper bound on the size of the
  // unescaped string.
  std::string result;
  size_t input_length = input.size();
  result.reserve(input_length);

  for (size_t i = 0; i < input_length; i++) {
    char c = input[i];
    if (c == '\\') {
      // Escaped literal, slip the backslash, append the next character.
      i++;
      if (i < input_length)
        result.push_back(input[i]);
    } else if (c == '$') {
      // Dollar sign denotes a hex character.
      if (i < input_length - 2) {
        // Would be nice to use ToInteger() here, but it currently
        // requires a null-terminated string.
        int first = HexCharToInt(input[++i]);
        int second = HexCharToInt(input[++i]);
        if (first >= 0 && second >= 0)
          result.push_back((first << 4) | second);
      }
    } else {
      // Regular character, just append.
      result.push_back(input[i]);
    }
  }
  return result;
}

}  // namespace

MorkReader::MorkReader() {
}

MorkReader::~MorkReader() {
  // Need to delete all the pointers to vectors we have in the table.
  for (RowMap::iterator i = table_.begin(); i != table_.end(); ++i)
    delete i->second;
}

bool MorkReader::Read(const FilePath& path) {
  stream_.open(path.value().c_str());
  if (!stream_.is_open())
    return false;

  std::string line;
  if (!ReadLine(&line) ||
      line.compare("// <!-- <mdb:mork:z v=\"1.4\"/> -->") != 0)
    return false;  // Unexpected file format.

  IndexMap column_map;
  while (ReadLine(&line)) {
    // Trim off leading spaces
    size_t idx = 0;
    size_t len = line.size();
    while (idx < len && line[idx] == ' ')
      ++idx;
    if (idx >= len)
      continue;

    // Look at the line to figure out what section type this is
    if (StartsWithASCII(&line[idx], "< <(a=c)>", true)) {
      // Column map.  We begin by creating a hash of column id to column name.
      StringMap column_name_map;
      ParseMap(line, idx, &column_name_map);

      // Now that we have the list of columns, we put them into a flat array.
      // Rows will have value arrays of the same size, with indexes that
      // correspond to the columns array.  As we insert each column into the
      // array, we also make an entry in columnMap so that we can look up the
      // index given the column id.
      columns_.reserve(column_name_map.size());

      for (StringMap::const_iterator i = column_name_map.begin();
           i != column_name_map.end(); ++i) {
        column_map[i->first] = static_cast<int>(columns_.size());
        MorkColumn col(i->first, i->second);
        columns_.push_back(col);
      }
    } else if (StartsWithASCII(&line[idx], "<(", true)) {
      // Value map.
      ParseMap(line, idx, &value_map_);
    } else if (line[idx] == '{' || line[idx] == '[') {
      // Table / table row.
      ParseTable(line, idx, &column_map);
    } else {
      // Don't know, hopefully don't care.
    }
  }
  return true;
}

// Parses a key/value map of the form
// <(k1=v1)(k2=v2)...>
bool MorkReader::ParseMap(const std::string& first_line,
                          size_t start_index,
                          StringMap* map) {
  // If the first line is the a=c line (column map), just skip over it.
  std::string line(first_line);
  if (StartsWithASCII(line, "< <(a=c)>", true))
    ReadLine(&line);

  std::string key;
  do {
    size_t idx = start_index;
    size_t len = line.size();
    size_t token_start;

    while (idx < len) {
      switch (line[idx++]) {
        case '(':
          // Beginning of a key/value pair.
          if (!key.empty()) {
            DLOG(WARNING) << "unterminated key/value pair?";
            key.clear();
          }

          token_start = idx;
          while (idx < len && line[idx] != '=')
            ++idx;
          key.assign(&line[token_start], idx - token_start);
          break;

        case '=': {
          // Beginning of the value.
          if (key.empty()) {
            DLOG(WARNING) << "stray value";
            break;
          }

          token_start = idx;
          while (idx < len && line[idx] != ')') {
            if (line[idx] == '\\')
              ++idx;  // Skip escaped ')' characters.
            ++idx;
          }
          size_t token_end = std::min(idx, len);
          ++idx;

          std::string value = MorkUnescape(
              std::string(&line[token_start], token_end - token_start));
          (*map)[key] = value;
          key.clear();
          break;
        }
        case '>':
          // End of the map.
          DLOG_IF(WARNING, key.empty()) <<
              "map terminates inside of key/value pair";
          return true;
      }
    }

    // We should start reading the next line at the beginning.
    start_index = 0;
  } while (ReadLine(&line));

  // We ran out of lines and the map never terminated.  This probably indicates
  // a parsing error.
  DLOG(WARNING) << "didn't find end of key/value map";
  return false;
}

// Parses a table row of the form [123(^45^67)..]
// (row id 123 has the value with id 67 for the column with id 45).
// A '^' prefix for a column or value references an entry in the column or
// value map.  '=' is used as the separator when the value is a literal.
void MorkReader::ParseTable(const std::string& first_line,
                            size_t start_index,
                            const IndexMap* column_map) {
  std::string line(first_line);

  // Column index of the cell we're parsing, minus one if invalid.
  int column_index = -1;

  // Points to the current row we're parsing inside of the |table_|, will be
  // NULL if we're not inside a row.
  ColumnDataList* current_row = NULL;

  bool in_meta_row = false;

  do {
    size_t idx = start_index;
    size_t len = line.size();

    while (idx < len) {
      switch (line[idx++]) {
        case '{':
          // This marks the beginning of a table section.  There's a lot of
          // junk before the first row that looks like cell values but isn't.
          // Skip to the first '['.
          while (idx < len && line[idx] != '[') {
            if (line[idx] == '{') {
              in_meta_row = true;  // The meta row is enclosed in { }
            } else if (line[idx] == '}') {
              in_meta_row = false;
            }
            ++idx;
          }
          break;

        case '[': {
          // Start of a new row.  Consume the row id, up to the first '('.
          // Row edits also have a table namespace, separated from the row id
          // by a colon.  We don't make use of the namespace, but we need to
          // make sure not to consider it part of the row id.
          if (current_row) {
            DLOG(WARNING) << "unterminated row?";
            current_row = NULL;
          }

          // Check for a '-' at the start of the id.  This signifies that
          // if the row already exists, we should delete all columns from it
          // before adding the new values.
          bool cut_columns;
          if (idx < len && line[idx] == '-') {
            cut_columns = true;
            ++idx;
          } else {
            cut_columns = false;
          }

          // Locate the range of the ID.
          size_t token_start = idx;  // Index of the first char of the token.
          while (idx < len &&
                 line[idx] != '(' &&
                 line[idx] != ']' &&
                 line[idx] != ':') {
            ++idx;
          }
          size_t token_end = idx;  // Index of the char following the token.
          while (idx < len && line[idx] != '(' && line[idx] != ']') {
            ++idx;
          }

          if (in_meta_row) {
            // Need to create the meta row.
            meta_row_.resize(columns_.size());
            current_row = &meta_row_;
          } else {
            // Find or create the regular row for this.
            IDString row_id(&line[token_start], token_end - token_start);
            RowMap::iterator found_row = table_.find(row_id);
            if (found_row == table_.end()) {
              // We don't already have this row, create a new one for it.
              current_row = new ColumnDataList(columns_.size());
              table_[row_id] = current_row;
            } else {
              // The row already exists and we're adding/replacing things.
              current_row = found_row->second;
            }
          }
          if (cut_columns) {
            for (size_t i = 0; i < current_row->size(); ++i)
              (*current_row)[i].clear();
          }
          break;
        }

        case ']':
          // We're done with the row.
          current_row = NULL;
          in_meta_row = false;
          break;

        case '(': {
          if (!current_row) {
            DLOG(WARNING) << "cell value outside of row";
            break;
          }

          bool column_is_atom;
          if (line[idx] == '^') {
            column_is_atom = true;
            ++idx;  // This is not part of the column id, advance past it.
          } else {
            column_is_atom = false;
          }
          size_t token_start = idx;
          while (idx < len && line[idx] != '^' && line[idx] != '=') {
            if (line[idx] == '\\')
              ++idx;  // Skip escaped characters.
            ++idx;
          }

          size_t token_end = std::min(idx, len);

          IDString column;
          if (column_is_atom)
            column.assign(&line[token_start], token_end - token_start);
          else
            column = MorkUnescape(line.substr(token_start,
                                              token_end - token_start));

          IndexMap::const_iterator found_column = column_map->find(column);
          if (found_column == column_map->end()) {
            DLOG(WARNING) << "Column not in column map, discarding it";
            column_index = -1;
          } else {
            column_index = found_column->second;
          }
          break;
        }

        case '=':
        case '^': {
          if (column_index == -1) {
            DLOG(WARNING) << "stray ^ or = marker";
            break;
          }

          bool value_is_atom = (line[idx - 1] == '^');
          size_t token_start = idx - 1;  // Include the '=' or '^' marker.
          while (idx < len && line[idx] != ')') {
            if (line[idx] == '\\')
              ++idx;  // Skip escaped characters.
            ++idx;
          }
          size_t token_end = std::min(idx, len);
          ++idx;

          if (value_is_atom) {
            (*current_row)[column_index].assign(&line[token_start],
                                                token_end - token_start);
          } else {
            (*current_row)[column_index] =
                MorkUnescape(line.substr(token_start, token_end - token_start));
          }
          column_index = -1;
        }
        break;
      }
    }

    // Start parsing the next line at the beginning.
    start_index = 0;
  } while (current_row && ReadLine(&line));
}

bool MorkReader::ReadLine(std::string* line) {
  line->resize(256);
  std::getline(stream_, *line);
  if (stream_.eof() || stream_.bad())
    return false;

  while (!line->empty() &&  (*line)[line->size() - 1] == '\\') {
    // There is a continuation for this line.  Read it and append.
    std::string new_line;
    std::getline(stream_, new_line);
    if (stream_.eof())
      return false;
    line->erase(line->size() - 1);
    line->append(new_line);
  }

  return true;
}

void MorkReader::NormalizeValue(std::string* value) const {
  if (value->empty())
    return;
  MorkReader::StringMap::const_iterator i;
  switch (value->at(0)) {
    case '^':
      // Hex ID, lookup the name for it in the |value_map_|.
      i = value_map_.find(value->substr(1));
      if (i == value_map_.end())
        value->clear();
      else
        *value = i->second;
      break;
    case '=':
      // Just use the literal after the equals sign.
      value->erase(value->begin());
      break;
    default:
      // Anything else is invalid.
      value->clear();
      break;
  }
}

// Source:
// http://mxr.mozilla.org/firefox/source/toolkit/components/places/src/nsMorkHistoryImporter.cpp

// Columns for entry (non-meta) history rows
enum {
  kURLColumn,
  kNameColumn,
  kVisitCountColumn,
  kHiddenColumn,
  kTypedColumn,
  kLastVisitColumn,
  kColumnCount  // Keep me last.
};

static const char * const gColumnNames[] = {
  "URL", "Name", "VisitCount", "Hidden", "Typed", "LastVisitDate"
};

struct TableReadClosure {
  explicit TableReadClosure(const MorkReader& r)
      : reader(r),
        swap_bytes(false),
        byte_order_column(-1) {
    for (int i = 0; i < kColumnCount; ++i)
      column_indexes[i] = -1;
  }

  // Backpointers to the reader and history we're operating on.
  const MorkReader& reader;

  // Whether we need to swap bytes (file format is other-endian).
  bool swap_bytes;

  // Indexes of the columns that we care about.
  int column_indexes[kColumnCount];
  int byte_order_column;
};

void AddToHistory(MorkReader::ColumnDataList* column_values,
                  const TableReadClosure& data,
                  std::vector<history::URLRow>* rows) {
  std::string values[kColumnCount];

  for (size_t i = 0; i < kColumnCount; ++i) {
    if (data.column_indexes[i] != -1) {
      values[i] = column_values->at(data.column_indexes[i]);
      data.reader.NormalizeValue(&values[i]);
      // Do not import hidden records.
      if (i == kHiddenColumn && values[i] == "1")
        return;
    }
  }

  GURL url(values[kURLColumn]);

  if (CanImportURL(url)) {
    history::URLRow row(url);

    string16 title;
    if (data.swap_bytes) {
      base::CodepageToUTF16(values[kNameColumn], base::kCodepageUTF16BE,
                            base::OnStringConversionError::SKIP, &title);
    } else {
      base::CodepageToUTF16(values[kNameColumn], base::kCodepageUTF16LE,
                            base::OnStringConversionError::SKIP, &title);
    }
    row.set_title(title);

    int count = atoi(values[kVisitCountColumn].c_str());
    if (count == 0)
      count = 1;
    row.set_visit_count(count);

    int64 date;
    base::StringToInt64(values[kLastVisitColumn], &date);
    if (date != 0)
      row.set_last_visit(base::Time::FromTimeT(date / 1000000));

    bool is_typed = (values[kTypedColumn] == "1");
    if (is_typed)
      row.set_typed_count(1);

    rows->push_back(row);
  }
}

// It sets up the file stream and loops over the lines in the file to
// parse them, then adds the resulting row set to history.
void ImportHistoryFromFirefox2(const FilePath& file, ImporterBridge* bridge) {
  MorkReader reader;
  reader.Read(file);

  // Gather up the column ids so we don't need to find them on each row
  TableReadClosure data(reader);
  const MorkReader::MorkColumnList& columns = reader.columns();
  for (size_t i = 0; i < columns.size(); ++i) {
    for (int j = 0; j < kColumnCount; ++j)
      if (columns[i].name == gColumnNames[j]) {
        data.column_indexes[j] = static_cast<int>(i);
        break;
      }
    if (columns[i].name == "ByteOrder")
      data.byte_order_column = static_cast<int>(i);
  }

  // Determine the byte order from the table's meta-row.
  const MorkReader::ColumnDataList& meta_row = reader.meta_row();
  if (!meta_row.empty() && data.byte_order_column != -1) {
    std::string byte_order = meta_row[data.byte_order_column];
    if (!byte_order.empty()) {
      // Note whether the file uses a non-native byte ordering.
      // If it does, we'll have to swap bytes for PRUnichar values.
      // "BE" and "LE" are the only recognized values, anything
      // else is garbage and the file will be treated as native-endian
      // (no swapping).
      std::string byte_order_value(byte_order);
      reader.NormalizeValue(&byte_order_value);
      data.swap_bytes = (byte_order_value == "BE");
    }
  }

  std::vector<history::URLRow> rows;
  for (MorkReader::iterator i = reader.begin(); i != reader.end(); ++i)
    AddToHistory(i->second, data, &rows);
  if (!rows.empty())
    bridge->SetHistoryItems(rows, history::SOURCE_FIREFOX_IMPORTED);
}
