/**
 *   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 "query_execution/WorkOrdersContainer.hpp"

#include <algorithm>
#include <cstddef>
#include <list>
#include <memory>
#include <vector>

#include "relational_operators/WorkOrder.hpp"

#include "glog/logging.h"

using std::unique_ptr;

namespace quickstep {

WorkOrdersContainer::~WorkOrdersContainer() {
  // For each operator ..
  for (std::size_t op = 0; op < num_operators_; ++op) {
    if (hasNormalWorkOrder(op) || hasRebuildWorkOrder(op)) {
      LOG(WARNING) << "Destroying a WorkOrdersContainer that still has pending WorkOrders.";
      break;
    }
  }
}

WorkOrder* WorkOrdersContainer::InternalListContainer::getWorkOrderForNUMANode(
    const int numa_node) {
  for (std::list<unique_ptr<WorkOrder>>::iterator it = workorders_.begin();
       it != workorders_.end();
       ++it) {
    const std::vector<int> &numa_nodes = (*it)->getPreferredNUMANodes();
    if (!numa_nodes.empty()) {
      if (std::find(numa_nodes.begin(), numa_nodes.end(), numa_node) !=
          numa_nodes.end()) {
        WorkOrder *work_order = it->release();
        workorders_.erase(it);
        return work_order;
      }
    }
  }
  return nullptr;
}

void WorkOrdersContainer::OperatorWorkOrdersContainer::addWorkOrder(
    WorkOrder *workorder) {
  const std::vector<int> &numa_nodes = workorder->getPreferredNUMANodes();
  if (!numa_nodes.empty()) {
    if (numa_nodes.size() == 1) {
      // This WorkOrder prefers exactly one NUMA node.
      single_numa_node_workorders_[numa_nodes.front()].addWorkOrder(
          workorder);
    } else {
      // This WorkOrder prefers more than one NUMA node.
      multiple_numa_nodes_workorders_.addWorkOrder(workorder);
    }
  } else {
    numa_agnostic_workorders_.addWorkOrder(workorder);
  }
}

std::size_t
    WorkOrdersContainer::InternalListContainer::getNumWorkOrdersForNUMANode(
    const int numa_node) const {
  std::size_t num_workorders = 0;
  for (const unique_ptr<WorkOrder> &work_order : workorders_) {
    const std::vector<int> &numa_nodes = work_order->getPreferredNUMANodes();
    if (!numa_nodes.empty()) {
      std::vector<int>::const_iterator
          it = std::find(numa_nodes.begin(), numa_nodes.end(), numa_node);
      if (it != numa_nodes.end()) {
        // Found a match.
       ++num_workorders;
      }
    }
  }
  return num_workorders;
}

bool WorkOrdersContainer::InternalListContainer::hasWorkOrderForNUMANode(
    const int numa_node) const {
  for (const unique_ptr<WorkOrder> &work_order : workorders_) {
    const std::vector<int> &numa_nodes = work_order->getPreferredNUMANodes();
    if (!numa_nodes.empty()) {
      std::vector<int>::const_iterator
          it = std::find(numa_nodes.begin(), numa_nodes.end(), numa_node);
      if (it != numa_nodes.end()) {
        // Found a match.
        return true;
      }
    }
  }
  return false;
}

WorkOrder* WorkOrdersContainer::OperatorWorkOrdersContainer::getWorkOrder(
    const bool prefer_single_NUMA_node) {
  // This function tries to get any available WorkOrder.
  WorkOrder *workorder = numa_agnostic_workorders_.getWorkOrder();
  if (workorder == nullptr) {
    if (prefer_single_NUMA_node) {
      workorder = getSingleNUMANodeWorkOrderHelper();
      if (workorder == nullptr) {
        workorder = multiple_numa_nodes_workorders_.getWorkOrder();
      }
    } else {
      workorder = multiple_numa_nodes_workorders_.getWorkOrder();
      if (workorder == nullptr) {
        workorder = getSingleNUMANodeWorkOrderHelper();
      }
    }
  }
  return workorder;
}

WorkOrder* WorkOrdersContainer::OperatorWorkOrdersContainer::
    getSingleNUMANodeWorkOrderHelper() {
  WorkOrder *workorder = nullptr;
  for (PtrVector<InternalQueueContainer>::iterator it =
           single_numa_node_workorders_.begin();
       it != single_numa_node_workorders_.end(); ++it) {
    workorder = it->getWorkOrder();
    if (workorder != nullptr) {
      return workorder;
    }
  }
  return nullptr;
}

}  // namespace quickstep
