/**
 *   Copyright 2011-2015 Quickstep Technologies LLC.
 *   Copyright 2015-2016 Pivotal Software, Inc.
 *
 *   Licensed 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.
 **/

#include "catalog/PartitionScheme.hpp"

#include <cstddef>
#include <limits>
#include <unordered_set>
#include <utility>
#include <vector>

#include "catalog/Catalog.pb.h"
#include "catalog/PartitionSchemeHeader.hpp"
#include "storage/StorageBlockInfo.hpp"

#include "glog/logging.h"

using std::move;
using std::unordered_set;
using std::vector;

namespace quickstep {

bool PartitionScheme::ProtoIsValid(
    const serialization::PartitionScheme &proto) {
  // Check that proto is fully initialized.
  if (!proto.IsInitialized()) {
    return false;
  }

  if (!PartitionSchemeHeader::ProtoIsValid(proto.header())) {
    return false;
  }

  if (static_cast<std::size_t>(proto.partitions_size()) != proto.header().num_partitions()) {
    return false;
  }

  return true;
}

PartitionScheme* PartitionScheme::ReconstructFromProto(const serialization::PartitionScheme &proto,
                                                       const Type &attr_type) {
  DCHECK(ProtoIsValid(proto))
      << "Attempted to create PartitionScheme from an invalid proto description:\n"
      << proto.DebugString();

  vector<unordered_set<block_id>> blocks_in_partition;
  for (int i = 0; i < proto.partitions_size(); ++i) {
    unordered_set<block_id> blocks;

    const serialization::Partition &proto_blocks = proto.partitions(i);
    for (int j = 0; j < proto_blocks.blocks_size(); ++j) {
      blocks.insert(proto_blocks.blocks(j));
    }

    blocks_in_partition.push_back(move(blocks));
  }

  return new PartitionScheme(
      PartitionSchemeHeader::ReconstructFromProto(proto.header(), attr_type),
      move(blocks_in_partition));
}

serialization::PartitionScheme PartitionScheme::getProto() const {
  serialization::PartitionScheme proto;

  proto.mutable_header()->MergeFrom(header_->getProto());

  // Add blocks to the corresponding partitions.
  for (std::size_t i = 0; i < blocks_in_partition_.size(); ++i) {
    serialization::Partition *proto_blocks = proto.add_partitions();

    SpinSharedMutexSharedLock<false> lock(blocks_in_partition_mutexes_[i]);
    const std::unordered_set<block_id> &partition = blocks_in_partition_[i];
    for (const block_id block : partition) {
      proto_blocks->add_blocks(block);
    }
  }

  return proto;
}

partition_id PartitionScheme::getPartitionForBlock(const block_id block) const {
  // Check if the block is present in the available partitions.
  // If so, return the partition id for the block.
  for (partition_id part_id = 0; part_id < header_->getNumPartitions(); ++part_id) {
    SpinSharedMutexSharedLock<false> lock(
        blocks_in_partition_mutexes_[part_id]);
    if (blocks_in_partition_[part_id].find(block) !=
        blocks_in_partition_[part_id].end()) {
      return part_id;
    }
  }
  // Block was not found in any partitions.
  return std::numeric_limits<std::size_t>::max();
}

}  // namespace quickstep
