// 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 __COMMON_RESOURCE_QUANTITIES_HPP__
#define __COMMON_RESOURCE_QUANTITIES_HPP__

#include <string>
#include <utility>
#include <vector>

#include <mesos/mesos.hpp>
#include <mesos/resources.hpp>

#include <stout/try.hpp>

namespace mesos {
namespace internal {


// An efficient collection of resource quantities. All values are guaranteed
// to be positive and finite.
//
// E.g. [("cpus", 4.5), ("gpus", 0.1), ("ports", 1000)]
//
// Absent resource entries imply there is no (zero) such resources.
//
// TODO(mzhu): Add `class ResourceLimits` where absence means infinite amount
// of such resources.
//
// Notes on handling negativity and arithmetic operations: values are guaranteed
// to be positive. This is achieved by construction validation and no public
// mutation interfaces. During construction, `Value::Scalar` arguments must be
// non-negative and finite, and entries with zero quantities will be dropped
// silently. Invalid arguments will result in an error where `Try`
// is returned. For arithmetic operations, non-positive values are silently
// dropped--this is consist with `class Resources`.
//
// Note for posterity, the status quo prior to this class
// was to use stripped-down `Resources` objects for storing
// quantities, however this approach:
//
//   (1) did not support quantities of non-scalar resources;
//   (2) was error prone, the caller must ensure that no
//       `Resource` metatdata (e.g. `DiskInfo`) is present;
//   (3) had poor performance, given the `Resources` storage
//       model and arithmetic implementation have to operate
//       on broader invariants.
class ResourceQuantities
{
public:
  // Parse an input string of semicolon separated "name:number" pairs.
  // Duplicate names are allowed in the input and will be merged into one entry.
  // Entries with zero values will be silently dropped.
  //
  // Example: "cpus:10;mem:1024;ports:3"
  //          "cpus:10; mem:1024; ports:3"
  // NOTE: we will trim the whitespace around the pair and in the number.
  // However, whitespace in "c p us:10" are preserved and will be parsed to
  // {"c p us", 10}. This is consistent with `Resources::fromSimpleString()`.
  //
  // Numbers must be non-negative and finite, otherwise an `Error`
  // will be returned.
  static Try<ResourceQuantities> fromString(const std::string& text);

  // Take scalar `Resources` and combine them into `ResourceQuantities`.
  // Only the resource name and its scalar value are used and the rest of the
  // meta-data is ignored. It is caller's responsibility to ensure all
  // `Resource` entries are of scalar type. Otherwise a `CHECK` error will
  // be triggered.
  static ResourceQuantities fromScalarResources(const Resources& resources);

  // Take `Resources` and combine them into `ResourceQuantities`. This function
  // assumes that the provided resources have already been validated; for
  // example, it assumes that ranges do not overlap and that sets do not contain
  // duplicate items.
  static ResourceQuantities fromResources(const Resources& resources);

  ResourceQuantities();

  ResourceQuantities(const ResourceQuantities& that) = default;
  ResourceQuantities(ResourceQuantities&& that) = default;

  ResourceQuantities& operator=(const ResourceQuantities& that) = default;
  ResourceQuantities& operator=(ResourceQuantities&& that) = default;

  typedef std::vector<std::pair<std::string, Value::Scalar>>::const_iterator
    iterator;
  typedef std::vector<std::pair<std::string, Value::Scalar>>::const_iterator
    const_iterator;

  // NOTE: Non-`const` `iterator`, `begin()` and `end()` are __intentionally__
  // defined with `const` semantics in order to prevent mutation during
  // iteration. Mutation is allowed with the `[]` operator.
  const_iterator begin();
  const_iterator end();

  const_iterator begin() const { return quantities.begin(); }
  const_iterator end() const { return quantities.end(); }

  size_t size() const { return quantities.size(); };

  // Returns the quantity scalar value if a quantity with the given name.
  // If the given name is absent, return zero.
  Value::Scalar get(const std::string& name) const;

  bool operator==(const ResourceQuantities& quantities) const;
  bool operator!=(const ResourceQuantities& quantities) const;

  ResourceQuantities& operator+=(const ResourceQuantities& quantities);
  ResourceQuantities& operator-=(const ResourceQuantities& quantities);

private:
  void add(const std::string& name, const Value::Scalar& scalar);
  void add(const std::string& name, double value);

  // List of name quantity pairs sorted by name.
  // Arithmetic and comparison operations benefit from this sorting.
  std::vector<std::pair<std::string, Value::Scalar>> quantities;
};


} // namespace internal {
} // namespace mesos {

#endif //  __COMMON_RESOURCE_QUANTITIES_HPP__
