// 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_HTTP_HPP__
#define __COMMON_HTTP_HPP__

#include <vector>

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

#include <mesos/authorizer/authorizer.hpp>

#include <mesos/quota/quota.hpp>

#include <process/future.hpp>
#include <process/http.hpp>
#include <process/owned.hpp>

#include <stout/hashmap.hpp>
#include <stout/hashset.hpp>
#include <stout/json.hpp>
#include <stout/jsonify.hpp>
#include <stout/protobuf.hpp>
#include <stout/unreachable.hpp>

namespace mesos {

class Attributes;
class Resources;
class Task;

namespace internal {

// Name of the default, basic authenticator.
constexpr char DEFAULT_BASIC_HTTP_AUTHENTICATOR[] = "basic";

// Name of the default, JWT authenticator.
constexpr char DEFAULT_JWT_HTTP_AUTHENTICATOR[] = "jwt";

extern hashset<std::string> AUTHORIZABLE_ENDPOINTS;


// Contains the media types corresponding to some of the "Content-*",
// "Accept-*" and "Message-*" prefixed request headers in our internal
// representation.
struct RequestMediaTypes
{
  ContentType content; // 'Content-Type' header.
  ContentType accept; // 'Accept' header.
  Option<ContentType> messageContent; // 'Message-Content-Type' header.
  Option<ContentType> messageAccept; // 'Message-Accept' header.
};


// Serializes a protobuf message for transmission
// based on the HTTP content type.
// NOTE: For streaming `contentType`, `message` would not
// be serialized in "Record-IO" format.
std::string serialize(
    ContentType contentType,
    const google::protobuf::Message& message);


// Deserializes a string message into a protobuf message based on the
// HTTP content type.
template <typename Message>
Try<Message> deserialize(
    ContentType contentType,
    const std::string& body)
{
  switch (contentType) {
    case ContentType::PROTOBUF: {
      Message message;
      if (!message.ParseFromString(body)) {
        return Error("Failed to parse body into a protobuf object");
      }
      return message;
    }
    case ContentType::JSON: {
      Try<JSON::Value> value = JSON::parse(body);
      if (value.isError()) {
        return Error("Failed to parse body into JSON: " + value.error());
      }

      return ::protobuf::parse<Message>(value.get());
    }
    case ContentType::RECORDIO: {
      return Error("Deserializing a RecordIO stream is not supported");
    }
  }

  UNREACHABLE();
}


// Returns true if the media type can be used for
// streaming requests/responses.
bool streamingMediaType(ContentType contentType);


JSON::Object model(const Resources& resources);
JSON::Object model(const hashmap<std::string, Resources>& roleResources);
JSON::Object model(const Attributes& attributes);
JSON::Object model(const CommandInfo& command);
JSON::Object model(const ExecutorInfo& executorInfo);
JSON::Array model(const Labels& labels);
JSON::Object model(const Task& task);
JSON::Object model(const FileInfo& fileInfo);
JSON::Object model(const quota::QuotaInfo& quotaInfo);

void json(JSON::ObjectWriter* writer, const Task& task);

} // namespace internal {

void json(JSON::ObjectWriter* writer, const Attributes& attributes);
void json(JSON::ObjectWriter* writer, const CommandInfo& command);
void json(JSON::ObjectWriter* writer, const ExecutorInfo& executorInfo);
void json(JSON::ArrayWriter* writer, const Labels& labels);
void json(JSON::ObjectWriter* writer, const Resources& resources);
void json(JSON::ObjectWriter* writer, const Task& task);
void json(JSON::ObjectWriter* writer, const TaskStatus& status);
void json(JSON::ObjectWriter* writer, const DomainInfo& domainInfo);

namespace authorization {

// Creates a subject for authorization purposes when given an authenticated
// principal. This function accepts and returns an `Option` to make call sites
// cleaner, since it is possible that `principal` will be `NONE`.
const Option<authorization::Subject> createSubject(
    const Option<process::http::authentication::Principal>& principal);

} // namespace authorization {

const process::http::authorization::AuthorizationCallbacks
  createAuthorizationCallbacks(Authorizer* authorizer);


// Implementation of the `ObjectApprover` interface authorizing all objects.
class AcceptingObjectApprover : public ObjectApprover
{
public:
  virtual Try<bool> approved(
      const Option<ObjectApprover::Object>& object) const noexcept override
  {
    return true;
  }
};


// Determines which objects will be accepted based on authorization.
class AuthorizationAcceptor
{
public:
  static process::Future<process::Owned<AuthorizationAcceptor>> create(
      const Option<process::http::authentication::Principal>& principal,
      const Option<Authorizer*>& authorizer,
      const authorization::Action& action);

  template <typename... Args>
  bool accept(Args&... args)
  {
    Try<bool> approved =
      objectApprover->approved(ObjectApprover::Object(args...));
    if (approved.isError()) {
      LOG(WARNING) << "Error during authorization: " << approved.error();
      return false;
    }

    return approved.get();
  }

protected:
  // TODO(qleng): Currently, `Owned` is implemented with `shared_ptr` and allows
  // copying. In the future, if `Owned` is implemented with `unique_ptr`, we
  // will need to pass by rvalue reference here instead (see MESOS-5122).
  AuthorizationAcceptor(const process::Owned<ObjectApprover>& approver)
    : objectApprover(approver) {}

  const process::Owned<ObjectApprover> objectApprover;
};


/**
 * Used to filter results for API handlers. Provides the 'accept()' method to
 * test whether the supplied ID is equal to a stored target ID. If no target
 * ID is provided when the acceptor is constructed, it will accept all inputs.
 */
template <typename T>
class IDAcceptor
{
public:
  IDAcceptor(const Option<std::string>& id = None())
  {
    if (id.isSome()) {
      T targetId_;
      targetId_.set_value(id.get());
      targetId = targetId_;
    }
  }

  bool accept(const T& candidateId) const
  {
    if (targetId.isNone()) {
      return true;
    }

    return candidateId.value() == targetId->value();
  }

protected:
  Option<T> targetId;
};


bool approveViewFrameworkInfo(
    const process::Owned<ObjectApprover>& frameworksApprover,
    const FrameworkInfo& frameworkInfo);


bool approveViewExecutorInfo(
    const process::Owned<ObjectApprover>& executorsApprover,
    const ExecutorInfo& executorInfo,
    const FrameworkInfo& frameworkInfo);


bool approveViewTaskInfo(
    const process::Owned<ObjectApprover>& tasksApprover,
    const TaskInfo& taskInfo,
    const FrameworkInfo& frameworkInfo);


bool approveViewTask(
    const process::Owned<ObjectApprover>& tasksApprover,
    const Task& task,
    const FrameworkInfo& frameworkInfo);


bool approveViewFlags(const process::Owned<ObjectApprover>& flagsApprover);


// Authorizes access to an HTTP endpoint. The `method` parameter
// determines which ACL action will be used in the authorization.
// It is expected that the caller has validated that `method` is
// supported by this function. Currently "GET" is supported.
//
// TODO(nfnt): Prefer types instead of strings
// for `endpoint` and `method`, see MESOS-5300.
process::Future<bool> authorizeEndpoint(
    const std::string& endpoint,
    const std::string& method,
    const Option<Authorizer*>& authorizer,
    const Option<process::http::authentication::Principal>& principal);


bool approveViewRole(
    const process::Owned<ObjectApprover>& rolesApprover,
    const std::string& role);

// Authorizes resources in either the pre- or the post-reservation-refinement
// formats.
// TODO(arojas): Update this helper to only accept the
// post-reservation-refinement format once MESOS-7851 is resolved.
bool authorizeResource(
    const Resource& resource,
    const Option<process::Owned<AuthorizationAcceptor>>& acceptor);


/**
 * Helper function to create HTTP authenticators
 * for a given realm and register in libprocess.
 *
 * @param realm name of the realm.
 * @param authenticatorNames a vector of authenticator names.
 * @param credentials optional credentials for BasicAuthenticator only.
 * @param secretKey optional secret key for the JWTAuthenticator only.
 * @return nothing if authenticators are initialized and registered to
 *         libprocess successfully, or error if authenticators cannot
 *         be initialized.
 */
Try<Nothing> initializeHttpAuthenticators(
    const std::string& realm,
    const std::vector<std::string>& httpAuthenticatorNames,
    const Option<Credentials>& credentials = None(),
    const Option<std::string>& secretKey = None());


// Logs the request. Route handlers can compose this with the
// desired request handler to get consistent request logging.
void logRequest(const process::http::Request& request);

} // namespace mesos {

#endif // __COMMON_HTTP_HPP__
