/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 **/

#ifndef QUICKSTEP_CATALOG_INDEX_SCHEME_HPP_
#define QUICKSTEP_CATALOG_INDEX_SCHEME_HPP_

#include <algorithm>
#include <cstddef>
#include <string>
#include <unordered_map>
#include <vector>

#include "catalog/Catalog.pb.h"
#include "storage/StorageBlockLayout.pb.h"
#include "utility/Macros.hpp"

#include "glog/logging.h"

namespace quickstep {

/** \addtogroup Catalog
 *  @{
 */

/**
 * @brief The Index Scheme class which stores the information about
 *        various indicies defined for a particular relation.
 **/
class IndexScheme {
 public:
  typedef std::unordered_map<std::string, IndexSubBlockDescription>::const_iterator const_iterator;

  /**
   * @brief Constructor.
   **/
  IndexScheme() {
  }

  /**
   * @brief Reconstruct an Index Scheme from its serialized
   *        Protocol Buffer form.
   *
   * @param proto The Protocol Buffer serialization of a Index Scheme,
   *              previously produced by getProto().
   * @return The deserialied index scheme object.
   **/
  static IndexScheme* ReconstructFromProto(const serialization::IndexScheme &proto);

  /**
   * @brief Check whether a serialization::IndexScheme is fully-formed and
   *        all parts are valid.
   *
   * @param proto A serialized Protocol Buffer representation of a
   *              IndexScheme, originally generated by getProto().
   * @return Whether proto is fully-formed and valid.
   **/
  static bool ProtoIsValid(const serialization::IndexScheme &proto);

  /**
   * @brief Serialize the Index Scheme as Protocol Buffer.
   *
   * @return The Protocol Buffer representation of Index Scheme.
   **/
  serialization::IndexScheme getProto() const;

  /**
   * @brief Get the number of indices for the relation.
   *
   * @return The number of indices defined for the relation.
   **/
  inline std::size_t getNumIndices() const {
    return index_map_.size();
  }

  /**
   * @brief Check whether an index with the given exists or not.
   *
   * @param index_name Name of the index to be checked.
   * @return Whether the index exists or not.
   **/
  bool hasIndexWithName(const std::string &index_name) const {
    return index_map_.find(index_name) != index_map_.end();
  }

  /**
   * @brief Check whether an index with the given description
   *        containing the same attribute id and index type
   *        exists or not in the index map.
   *
   * @param index_descripton Index Description to check against.
   * @return Whether a similar index description was already defined or not.
   **/
  bool hasIndexWithDescription(const IndexSubBlockDescription &index_description_checked) const {
    // Iterate through every index description corresponding to each key in the index map.
    for (auto cit = index_map_.cbegin(); cit != index_map_.cend(); ++cit) {
      const IndexSubBlockDescription &index_description_expected = cit->second;
      // Check if the stored description matches the given description.
      if (areIndexDescriptionsSame(index_description_expected, index_description_checked)) {
        return true;
      }
    }
    return false;
  }

  /**
   * @brief Check whether two index descriptions are same or not.
   *        Two index descriptions are same if they have any matching
   *        attributes ids and same index type.
   *
   * @param description_expected First index description.
   * @param description_checked Second index description.
   * @return Whether the two index_descriptions are similar or not.
   **/
  bool areIndexDescriptionsSame(const IndexSubBlockDescription &description_expected,
                                const IndexSubBlockDescription &description_checked) const {
    if (description_expected.sub_block_type() != description_checked.sub_block_type()) {
      return false;
    }

    // Serialize and sort the two protobuf index descriptions and compare.
    std::string serialized_description_expected, serialized_description_checked;
    description_expected.SerializeToString(&serialized_description_expected);
    description_checked.SerializeToString(&serialized_description_checked);
    std::sort(serialized_description_expected.begin(), serialized_description_expected.end());
    std::sort(serialized_description_checked.begin(), serialized_description_checked.end());

    return (serialized_description_expected.compare(serialized_description_checked) == 0);
  }

  /**
   * @brief Get an iterator at beginning of the index map.
   *
   * @return An iterator at beginning of the index map.
   **/
  inline const_iterator begin() const {
    return index_map_.begin();
  }

  /**
   * @brief Get an iterator at one-past-the-end of the index map.
   *
   * @return An iterator one-past-the-end of the index map.
   **/
  inline const_iterator end() const {
    return index_map_.end();
  }

  /**
   * @brief Adds a new index entry to the index map.
   * @warning Must call before hasIndexWithName() and hasIndexWithDescription().
   * @note This method assumes that the caller has already acquired the
   *       necessary locks before invoking it.
   *
   * @param index_name The name of index to add (key).
   * @param index_description The index description for this index (value).
   **/
  bool addIndexMapEntry(const std::string &index_name,
                        IndexSubBlockDescription &&index_description) {  // NOLINT(whitespace/operators)
    if (index_map_.find(index_name) != index_map_.end()) {
      return false;  // index_name is already present!
    }
    // Value for this index_map key is the index description provided.
    index_map_.emplace(index_name, std::move(index_description));
    return true;
  }

 private:
  // A map of index names to their index description.
  std::unordered_map<std::string, IndexSubBlockDescription> index_map_;

  DISALLOW_COPY_AND_ASSIGN(IndexScheme);
};

/** @} */

}  // namespace quickstep

#endif  // QUICKSTEP_CATALOG_INDEX_SCHEME_HPP_
