// 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.

#ifndef MOZC_CONVERTER_LATTICE_H_
#define MOZC_CONVERTER_LATTICE_H_

#include <string>
#include <vector>

#include "base/port.h"
#include "base/scoped_ptr.h"
#include "base/string_piece.h"
#include "converter/node.h"
#include "converter/node_allocator.h"

namespace mozc {

class Lattice {
 public:
  Lattice();
  ~Lattice();

  NodeAllocator *node_allocator() const;

  // set key and initalizes lattice with key.
  void SetKey(StringPiece key);

  // return key.
  const string& key() const;

  // Set history end position.
  // For cache, we have to reset lattice when the history size is changed.
  void set_history_end_pos(size_t pos);

  size_t history_end_pos() const;

  // allocate new node.
  Node *NewNode();

  // return nodes (linked list) starting with |pos|.
  // To traverse all nodes, use Node::bnext member.
  Node *begin_nodes(size_t pos) const;

  // return nodes (linked list) ending at |pos|.
  // To traverse all nodes, use Node::enext member.
  Node *end_nodes(size_t pos) const;

  // return bos nodes.
  // alias of end_nodes(0).
  Node *bos_nodes() const;

  // return eos nodes.
  // alias of begin_nodes(key.size()).
  Node *eos_nodes() const;

  // inset nodes (linked list) to the position |pos|.
  void Insert(size_t pos, Node *node);

  // clear all lattice and nodes allocated with NewNode method.
  void Clear();

  // return true if this instance has a valid lattice.
  bool has_lattice() const;

  // set key with cache information kept
  void UpdateKey(const string &new_key);

  // add suffix_key to the end of a current key
  void AddSuffix(const string &suffix_key);

  // erase the suffix of a key so that the length of the key becomes new_len
  void ShrinkKey(const size_t new_len);

  // getter
  size_t cache_info(const size_t pos) const;

  // setter
  void SetCacheInfo(const size_t pos, const size_t len);

  // revert the wcost of nodes if it has ENABLE_CACHE attribute.
  // This function is needed for wcost may be changed during conversion
  // process for some heuristic methods.
  void ResetNodeCost();

  // Dump the best path and the path that contains the designated string.
  string DebugString() const;

  // Set the node info that should be used in DebugString() (For debug use).
  static void SetDebugDisplayNode(size_t start_pos, size_t end_pos,
                                  const string &str);

  // Reset the debug info.
  static void ResetDebugDisplayNode();

 private:
  // TODO(team): Splitting the cache module may make this module simpler.
  string key_;
  size_t history_end_pos_;
  vector<Node *> begin_nodes_;
  vector<Node *> end_nodes_;
  scoped_ptr<NodeAllocator> node_allocator_;

  // cache_info_ holds cache information about lookup.
  // If cache_info_[pos] equals to len, it means key.substr(pos, k)
  // (1 <= k <= len) is already looked up.
  vector<size_t> cache_info_;
};

}  // namespace mozc

#endif  // MOZC_CONVERTER_LATTICE_H_
