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

#include <ostream>

#include <google/protobuf/util/message_differencer.h>

#include <stout/protobuf.hpp>
#include <stout/uuid.hpp>

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

using std::ostream;
using std::string;
using std::vector;

namespace mesos {
namespace v1 {

// TODO(vinod): Ensure that these operators do not go out of sync
// when new fields are added to the protobufs (MESOS-2487).

bool operator==(const CommandInfo& left, const CommandInfo& right)
{
  if (left.uris().size() != right.uris().size()) {
    return false;
  }

  // TODO(vinod): Factor out the comparison for repeated fields.
  for (int i = 0; i < left.uris().size(); i++) {
    bool found = false;
    for (int j = 0; j < right.uris().size(); j++) {
      if (left.uris().Get(i) == right.uris().Get(j)) {
        found = true;
        break;
      }
    }
    if (!found) {
      return false;
    }
  }

  if (left.arguments().size() != right.arguments().size()) {
    return false;
  }

  // The order of argv is important.
  for (int i = 0; i < left.arguments().size(); i++) {
    if (left.arguments().Get(i) != right.arguments().Get(i)) {
      return false;
    }
  }

  // NOTE: We are not validating CommandInfo::ContainerInfo here
  // because it is being deprecated in favor of ContainerInfo.
  // TODO(vinod): Kill the above comment when
  // CommandInfo::ContainerInfo is removed.
  return left.environment() == right.environment() &&
    left.value() == right.value() &&
    left.user() == right.user() &&
    left.shell() == right.shell();
}


bool operator==(const CommandInfo::URI& left, const CommandInfo::URI& right)
{
  return left.value() == right.value() &&
    left.executable() == right.executable() &&
    left.extract() == right.extract();
}


bool operator==(const Credential& left, const Credential& right)
{
  return left.principal() == right.principal() &&
    left.secret() == right.secret();
}


bool operator==(const CSIPluginInfo& left, const CSIPluginInfo& right)
{
  // Order of containers is important.
  if (left.containers_size() != right.containers_size()) {
    return false;
  }

  for (int i = 0; i < left.containers_size(); i++) {
    if (left.containers(i) != right.containers(i)) {
      return false;
    }
  }

  return left.type() == right.type() &&
    left.name() == right.name();
}


bool operator==(
    const CSIPluginContainerInfo& left,
    const CSIPluginContainerInfo& right)
{
  // Order of services is not important.
  if (left.services_size() != right.services_size()) {
    return false;
  }

  vector<bool> used(right.services_size(), false);

  for (int i = 0; i < left.services_size(); i++) {
    bool found = false;
    for (int j = 0; j < right.services_size(); j++) {
      if (left.services(i) == right.services(j) && !used[j]) {
        found = used[j] = true;
        break;
      }
    }
    if (!found) {
      return false;
    }
  }

  return left.has_command() == right.has_command() &&
    (!left.has_command() || left.command() == right.command()) &&
    Resources(left.resources()) == Resources(right.resources()) &&
    left.has_container() == right.has_container() &&
    (!left.has_container() || left.container() == right.container());
}


bool operator==(
    const Environment::Variable& left,
    const Environment::Variable& right)
{
  return left.name() == right.name() && left.value() == right.value();
}


bool operator==(const Environment& left, const Environment& right)
{
  // Order of variables is not important.
  if (left.variables().size() != right.variables().size()) {
    return false;
  }

  for (int i = 0; i < left.variables().size(); i++) {
    bool found = false;
    for (int j = 0; j < right.variables().size(); j++) {
      if (left.variables().Get(i) == right.variables().Get(j)) {
        found = true;
        break;
      }
    }
    if (!found) {
      return false;
    }
  }

  return true;
}


bool operator==(const Volume& left, const Volume& right)
{
  return left.container_path() == right.container_path() &&
    left.host_path() == right.host_path() &&
    left.mode() == right.mode();
}


// TODO(bmahler): Leverage process::http::URL for equality.
bool operator==(const URL& left, const URL& right)
{
  return left.SerializeAsString() == right.SerializeAsString();
}


bool operator==(
    const ContainerInfo::DockerInfo::PortMapping& left,
    const ContainerInfo::DockerInfo::PortMapping& right)
{
  return left.host_port() == right.host_port() &&
    left.container_port() == right.container_port() &&
    left.protocol() == right.protocol();
}


bool operator==(const Parameter& left, const Parameter& right)
{
  return left.key() == right.key() && left.value() == right.value();
}


bool operator==(
    const ContainerInfo::DockerInfo& left,
    const ContainerInfo::DockerInfo& right)
{
  // Order of port mappings is not important.
  if (left.port_mappings().size() != right.port_mappings().size()) {
    return false;
  }

  for (int i = 0; i < left.port_mappings().size(); i++) {
    bool found = false;
    for (int j = 0; j < right.port_mappings().size(); j++) {
      if (left.port_mappings().Get(i) == right.port_mappings().Get(j)) {
        found = true;
        break;
      }
    }
    if (!found) {
      return false;
    }
  }

  // Order of parameters is not important.
  if (left.parameters().size() != right.parameters().size()) {
    return false;
  }

  for (int i = 0; i < left.parameters().size(); i++) {
    bool found = false;
    for (int j = 0; j < right.parameters().size(); j++) {
      if (left.parameters().Get(i) == right.parameters().Get(j)) {
        found = true;
        break;
      }
    }
    if (!found) {
      return false;
    }
  }

  return left.image() == right.image() &&
    left.network() == right.network() &&
    left.privileged() == right.privileged() &&
    left.force_pull_image() == right.force_pull_image();
}


bool operator==(const ContainerInfo& left, const ContainerInfo& right)
{
  // Order of volumes is not important.
  if (left.volumes().size() != right.volumes().size()) {
    return false;
  }

  for (int i = 0; i < left.volumes().size(); i++) {
    bool found = false;
    for (int j = 0; j < right.volumes().size(); j++) {
      if (left.volumes().Get(i) == right.volumes().Get(j)) {
        found = true;
        break;
      }
    }
    if (!found) {
      return false;
    }
  }

  return left.type() == right.type() &&
    left.hostname() == right.hostname() &&
    left.docker() == right.docker();
}


bool operator==(const Port& left, const Port& right)
{
  return left.number() == right.number() &&
    left.name() == right.name() &&
    left.protocol() == right.protocol() &&
    left.visibility() == right.visibility();
}


bool operator==(const Ports& left, const Ports& right)
{
  // Order of ports is not important.
  if (left.ports().size() != right.ports().size()) {
    return false;
  }

  for (int i = 0; i < left.ports().size(); i++) {
    bool found = false;
    for (int j = 0; j < right.ports().size(); j++) {
      if (left.ports().Get(i) == right.ports().Get(j)) {
        found = true;
        break;
      }
    }
    if (!found) {
      return false;
    }
  }

  return true;
}


bool operator==(const Label& left, const Label& right)
{
  return left.key() == right.key() && left.value() == right.value();
}


bool operator==(const Labels& left, const Labels& right)
{
  // Order of labels is not important.
  if (left.labels().size() != right.labels().size()) {
    return false;
  }

  for (int i = 0; i < left.labels().size(); i++) {
    bool found = false;
    for (int j = 0; j < right.labels().size(); j++) {
      if (left.labels().Get(i) == right.labels().Get(j)) {
        found = true;
        break;
      }
    }
    if (!found) {
      return false;
    }
  }

  return true;
}


bool operator!=(const Labels& left, const Labels& right)
{
  return !(left == right);
}


bool operator==(const DiscoveryInfo& left, const DiscoveryInfo& right)
{
  return left.visibility() == right.visibility() &&
    left.name() == right.name() &&
    left.environment() == right.environment() &&
    left.location() == right.location() &&
    left.version() == right.version() &&
    left.ports() == right.ports() &&
    left.labels() == right.labels();
}


bool operator==(const ExecutorInfo& left, const ExecutorInfo& right)
{
  return left.executor_id() == right.executor_id() &&
    left.data() == right.data() &&
    Resources(left.resources()) == Resources(right.resources()) &&
    left.command() == right.command() &&
    left.framework_id() == right.framework_id() &&
    left.name() == right.name() &&
    left.source() == right.source() &&
    left.container() == right.container() &&
    left.discovery() == right.discovery();
}


bool operator==(const FileInfo& left, const FileInfo& right)
{
  return left.path() == right.path() &&
    left.nlink() == right.nlink() &&
    left.size() == right.size() &&
    left.mtime() == right.mtime() &&
    left.mode() == right.mode() &&
    left.uid() == right.uid() &&
    left.gid() == right.gid();
}


bool operator==(const MasterInfo& left, const MasterInfo& right)
{
  return left.id() == right.id() &&
    left.ip() == right.ip() &&
    left.port() == right.port() &&
    left.pid() == right.pid() &&
    left.hostname() == right.hostname() &&
    left.version() == right.version() &&
    left.domain() == right.domain();
}


bool operator==(const Offer::Operation& left, const Offer::Operation& right)
{
  return google::protobuf::util::MessageDifferencer::Equals(left, right);
}


bool operator==(const Operation& left, const Operation& right)
{
  return google::protobuf::util::MessageDifferencer::Equals(left, right);
}


bool operator!=(const Offer::Operation& left, const Offer::Operation& right)
{
  return !(left == right);
}


bool operator!=(const Operation& left, const Operation& right)
{
  return !(left == right);
}


bool operator==(
    const ResourceProviderInfo::Storage& left,
    const ResourceProviderInfo::Storage& right)
{
  return left.plugin() == right.plugin();
}


bool operator==(
    const ResourceProviderInfo& left,
    const ResourceProviderInfo& right)
{
  // Order of reservations is important.
  if (left.default_reservations_size() != right.default_reservations_size()) {
    return false;
  }

  for (int i = 0; i < left.default_reservations_size(); i++) {
    if (left.default_reservations(i) != right.default_reservations(i)) {
      return false;
    }
  }

  return left.has_id() == right.has_id() &&
    (!left.has_id() || left.id() == right.id()) &&
    Attributes(left.attributes()) == Attributes(right.attributes()) &&
    left.type() == right.type() &&
    left.name() == right.name() &&
    left.has_storage() == right.has_storage() &&
    (!left.has_storage() || left.storage() == right.storage());
}


bool operator==(
    const ResourceStatistics& left,
    const ResourceStatistics& right)
{
  return left.SerializeAsString() == right.SerializeAsString();
}


bool operator==(const AgentInfo& left, const AgentInfo& right)
{
  return left.hostname() == right.hostname() &&
    Resources(left.resources()) == Resources(right.resources()) &&
    Attributes(left.attributes()) == Attributes(right.attributes()) &&
    left.id() == right.id() &&
    left.port() == right.port() &&
    left.domain() == right.domain();
}


// TODO(bmahler): Use SerializeToString here?
bool operator==(const TaskStatus& left, const TaskStatus& right)
{
  return left.task_id() == right.task_id() &&
    left.state() == right.state() &&
    left.data() == right.data() &&
    left.message() == right.message() &&
    left.agent_id() == right.agent_id() &&
    left.timestamp() == right.timestamp() &&
    left.executor_id() == right.executor_id() &&
    left.healthy() == right.healthy() &&
    left.source() == right.source() &&
    left.reason() == right.reason() &&
    left.uuid() == right.uuid();
}


bool operator!=(const TaskStatus& left, const TaskStatus& right)
{
  return !(left == right);
}


ostream& operator<<(ostream& stream, const CapabilityInfo& capabilityInfo)
{
  return stream << JSON::protobuf(capabilityInfo);
}


ostream& operator<<(ostream& stream, const CheckStatusInfo& checkStatusInfo)
{
  switch (checkStatusInfo.type()) {
    case CheckInfo::COMMAND:
      if (checkStatusInfo.has_command()) {
        stream << "COMMAND";
        if (checkStatusInfo.command().has_exit_code()) {
          stream << " exit code " << checkStatusInfo.command().exit_code();
        }
      }
      break;
    case CheckInfo::HTTP:
      if (checkStatusInfo.has_http()) {
        stream << "HTTP";
        if (checkStatusInfo.http().has_status_code()) {
          stream << " status code " << checkStatusInfo.http().status_code();
        }
      }
      break;
    case CheckInfo::TCP:
      if (checkStatusInfo.has_tcp()) {
        stream << "TCP";
        if (checkStatusInfo.tcp().has_succeeded()) {
          stream << (checkStatusInfo.tcp().succeeded() ? " connection success"
                                                       : " connection failure");
        }
      }
      break;
    case CheckInfo::UNKNOWN:
      stream << "UNKNOWN";
      break;
  }

  return stream;
}


ostream& operator<<(ostream& stream, const ContainerID& containerId)
{
  return stream << containerId.value();
}


ostream& operator<<(ostream& stream, const ContainerInfo& containerInfo)
{
  return stream << containerInfo.DebugString();
}


ostream& operator<<(ostream& stream, const DomainInfo& domainInfo)
{
  return stream << JSON::protobuf(domainInfo);
}


ostream& operator<<(ostream& stream, const ExecutorID& executorId)
{
  return stream << executorId.value();
}


ostream& operator<<(ostream& stream, const ExecutorInfo& executor)
{
  return stream << executor.DebugString();
}


ostream& operator<<(ostream& stream, const FrameworkID& frameworkId)
{
  return stream << frameworkId.value();
}


ostream& operator<<(ostream& stream, const MasterInfo& master)
{
  return stream << master.DebugString();
}


ostream& operator<<(ostream& stream, const OfferID& offerId)
{
  return stream << offerId.value();
}


ostream& operator<<(ostream& stream, const OperationID& operationId)
{
  return stream << operationId.value();
}


ostream& operator<<(ostream& stream, const OperationState& state)
{
  return stream << OperationState_Name(state);
}


ostream& operator<<(ostream& stream, const RateLimits& limits)
{
  return stream << limits.DebugString();
}


ostream& operator<<(
    ostream& stream,
    const ResourceProviderID& resourceProviderId)
{
  return stream << resourceProviderId.value();
}


ostream& operator<<(
    ostream& stream,
    const ResourceProviderInfo& resourceProviderInfo)
{
  return stream << JSON::protobuf(resourceProviderInfo);
}


ostream& operator<<(ostream& stream, const RLimitInfo& limits)
{
  return stream << JSON::protobuf(limits);
}


ostream& operator<<(ostream& stream, const TaskStatus& status)
{
  stream << status.state();

  if (status.has_uuid()) {
    stream << " (Status UUID: "
           << stringify(id::UUID::fromBytes(status.uuid()).get()) << ")";
  }

  if (status.has_source()) {
    stream << " Source: " << TaskStatus::Source_Name(status.source());
  }

  if (status.has_reason()) {
    stream << " Reason: " << TaskStatus::Reason_Name(status.reason());
  }

  if (status.has_message()) {
    stream << " Message: '" << status.message() << "'";
  }

  stream << " for task '" << status.task_id() << "'";

  if (status.has_agent_id()) {
    stream << " on agent: " << status.agent_id() << "";
  }

  if (status.has_healthy()) {
    stream << " in health state "
           << (status.healthy() ? "healthy" : "unhealthy");
  }

  return stream;
}


ostream& operator<<(ostream& stream, const AgentID& agentId)
{
  return stream << agentId.value();
}


ostream& operator<<(ostream& stream, const AgentInfo& agent)
{
  return stream << agent.DebugString();
}


ostream& operator<<(ostream& stream, const TaskID& taskId)
{
  return stream << taskId.value();
}


ostream& operator<<(ostream& stream, const MachineID& machineId)
{
  if (machineId.has_hostname() && machineId.has_ip()) {
    return stream << machineId.hostname() << " (" << machineId.ip() << ")";
  }

  // If only a hostname is present.
  if (machineId.has_hostname()) {
    return stream << machineId.hostname();
  } else { // If there is no hostname, then there is an IP.
    return stream << "(" << machineId.ip() << ")";
  }
}


ostream& operator<<(ostream& stream, const TaskInfo& task)
{
  return stream << task.DebugString();
}


ostream& operator<<(ostream& stream, const TaskGroupInfo& taskGroupInfo)
{
  return stream << taskGroupInfo.DebugString();
}


ostream& operator<<(ostream& stream, const TaskState& state)
{
  return stream << TaskState_Name(state);
}


ostream& operator<<(ostream& stream, const CheckInfo::Type& type)
{
  return stream << CheckInfo::Type_Name(type);
}


ostream& operator<<(
    ostream& stream,
    const CSIPluginContainerInfo::Service& service)
{
  return stream << CSIPluginContainerInfo::Service_Name(service);
}


ostream& operator<<(
    ostream& stream,
    const FrameworkInfo::Capability& capability)
{
  return stream << FrameworkInfo::Capability::Type_Name(capability.type());
}


ostream& operator<<(ostream& stream, const Image::Type& imageType)
{
  return stream << Image::Type_Name(imageType);
}


ostream& operator<<(ostream& stream, const Secret::Type& secretType)
{
  return stream << Secret::Type_Name(secretType);
}


ostream& operator<<(
    ostream& stream,
    const Offer::Operation::Type& operationType)
{
  return stream << Offer::Operation::Type_Name(operationType);
}


ostream& operator<<(
    ostream& stream,
    const Resource::DiskInfo::Source::Type& sourceType)
{
  return stream << Resource::DiskInfo::Source::Type_Name(sourceType);
}

} // namespace v1 {
} // namespace mesos {
