/*
 *
 * Copyright 2015, Google Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#ifndef GRPCXX_CREDENTIALS_H
#define GRPCXX_CREDENTIALS_H

#include <chrono>
#include <memory>

#include <grpc++/config.h>
#include <grpc++/impl/grpc_library.h>

namespace grpc {
class ChannelArguments;
class ChannelInterface;
class SecureCredentials;

class Credentials : public GrpcLibrary {
 public:
  ~Credentials() GRPC_OVERRIDE;

 protected:
  friend std::unique_ptr<Credentials> CompositeCredentials(
      const std::unique_ptr<Credentials>& creds1,
      const std::unique_ptr<Credentials>& creds2);

  virtual SecureCredentials* AsSecureCredentials() = 0;

 private:
  friend std::shared_ptr<ChannelInterface> CreateChannel(
      const grpc::string& target, const std::unique_ptr<Credentials>& creds,
      const ChannelArguments& args);

  virtual std::shared_ptr<ChannelInterface> CreateChannel(
      const grpc::string& target, const ChannelArguments& args) = 0;
};

// Options used to build SslCredentials
// pem_roots_cert is the buffer containing the PEM encoding of the server root
// certificates. If this parameter is empty, the default roots will be used.
// pem_private_key is the buffer containing the PEM encoding of the client's
// private key. This parameter can be empty if the client does not have a
// private key.
// pem_cert_chain is the buffer containing the PEM encoding of the client's
// certificate chain. This parameter can be empty if the client does not have
// a certificate chain.
struct SslCredentialsOptions {
  grpc::string pem_root_certs;
  grpc::string pem_private_key;
  grpc::string pem_cert_chain;
};

// Factories for building different types of Credentials
// The functions may return empty unique_ptr when credentials cannot be created.
// If a Credentials pointer is returned, it can still be invalid when used to
// create a channel. A lame channel will be created then and all rpcs will
// fail on it.

// Builds credentials with reasonable defaults.
std::unique_ptr<Credentials> GoogleDefaultCredentials();

// Builds SSL Credentials given SSL specific options
std::unique_ptr<Credentials> SslCredentials(
    const SslCredentialsOptions& options);

// Builds credentials for use when running in GCE
std::unique_ptr<Credentials> ComputeEngineCredentials();

// Builds service account credentials.
// json_key is the JSON key string containing the client's private key.
// scope is a space-delimited list of the requested permissions.
// token_lifetime is the lifetime of each token acquired through this service
// account credentials. It should be positive and should not exceed
// grpc_max_auth_token_lifetime or will be cropped to this value.
std::unique_ptr<Credentials> ServiceAccountCredentials(
    const grpc::string& json_key, const grpc::string& scope,
    std::chrono::seconds token_lifetime);

// Builds JWT credentials.
// json_key is the JSON key string containing the client's private key.
// token_lifetime is the lifetime of each Json Web Token (JWT) created with
// this credentials.  It should not exceed grpc_max_auth_token_lifetime or
// will be cropped to this value.
std::unique_ptr<Credentials> JWTCredentials(
    const grpc::string& json_key, std::chrono::seconds token_lifetime);

// Builds refresh token credentials.
// json_refresh_token is the JSON string containing the refresh token along
// with a client_id and client_secret.
std::unique_ptr<Credentials> RefreshTokenCredentials(
    const grpc::string& json_refresh_token);

// Builds IAM credentials.
std::unique_ptr<Credentials> IAMCredentials(
    const grpc::string& authorization_token,
    const grpc::string& authority_selector);

// Combines two credentials objects into a composite credentials
std::unique_ptr<Credentials> CompositeCredentials(
    const std::unique_ptr<Credentials>& creds1,
    const std::unique_ptr<Credentials>& creds2);

// Credentials for an unencrypted, unauthenticated channel
std::unique_ptr<Credentials> InsecureCredentials();

}  // namespace grpc

#endif  // GRPCXX_CREDENTIALS_H
