/**
 * 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 PULSAR_AUTHENTICATION_H_
#define PULSAR_AUTHENTICATION_H_

#include <pulsar/Result.h>
#include <pulsar/defines.h>

#include <functional>
#include <map>
#include <memory>
#include <string>
#include <vector>

namespace pulsar {

class ClientConfiguration;
class Authentication;

class PULSAR_PUBLIC AuthenticationDataProvider {
   public:
    virtual ~AuthenticationDataProvider();

    /**
     * @return true if the authentication data contains data for TLS
     */
    virtual bool hasDataForTls();

    /**
     * @return a client certificate chain or “none” if the data is not available
     */
    virtual std::string getTlsCertificates();

    /**
     * @return a private key for the client certificate or “none” if the data is not available
     */
    virtual std::string getTlsPrivateKey();

    /**
     * @return true if this authentication data contains data for HTTP
     */
    virtual bool hasDataForHttp();

    /**
     * @return an authentication scheme or “none” if the request is not authenticated
     */
    virtual std::string getHttpAuthType();

    /**
     * @return the string of HTTP header or “none” if the request is not authenticated
     */
    virtual std::string getHttpHeaders();

    /**
     * @return true if authentication data contains data from Pulsar protocol
     */
    virtual bool hasDataFromCommand();

    /**
     * @return authentication data which is stored in a command
     */
    virtual std::string getCommandData();

   protected:
    AuthenticationDataProvider();
};

typedef std::shared_ptr<AuthenticationDataProvider> AuthenticationDataPtr;
typedef std::shared_ptr<Authentication> AuthenticationPtr;
typedef std::map<std::string, std::string> ParamMap;

class PULSAR_PUBLIC Authentication {
   public:
    virtual ~Authentication();

    /**
     * @return the authentication method name supported by this provider
     */
    virtual const std::string getAuthMethodName() const = 0;

    /**
     * Get AuthenticationData from the current instance
     *
     * @param[out] authDataContent the shared pointer of AuthenticationData. The content of AuthenticationData
     * is changed to the internal data of the current instance.
     * @return ResultOk or ResultAuthenticationError if authentication failed
     */
    virtual Result getAuthData(AuthenticationDataPtr& authDataContent) {
        authDataContent = authData_;
        return ResultOk;
    }

    /**
     * Parse the authentication parameter string to a map whose key and value are both strings
     *
     * The parameter string can have multiple lines. The format of each line is a comma-separated “key:value”
     * string.
     *
     * For example, “k1:v1,k2:v2” is parsed to two key-value pairs `(k1, v1)` and `(k2, v2)`.
     *
     * @param authParamsString the authentication parameter string to be parsed
     * @return the parsed map whose key and value are both strings
     */
    static ParamMap parseDefaultFormatAuthParams(const std::string& authParamsString);

   protected:
    Authentication();
    AuthenticationDataPtr authData_;
    friend class ClientConfiguration;
};

/**
 * AuthFactory is used to create instances of Authentication class when
 * configuring a Client instance. It loads the authentication from an
 * external plugin.
 *
 * To use authentication methods that are internally supported, you should
 * use `AuthTls::create("my-cert.pem", "my-private.key")` or similar.
 */
class PULSAR_PUBLIC AuthFactory {
   public:
    static AuthenticationPtr Disabled();

    /**
     * Create an AuthenticationPtr with an empty ParamMap
     *
     * @see create(const std::string&, const ParamMap&)
     */
    static AuthenticationPtr create(const std::string& pluginNameOrDynamicLibPath);

    /**
     * Create an AuthenticationPtr with a ParamMap that is converted from authParamsString
     *
     * @see Authentication::parseDefaultFormatAuthParams
     * @see create(const std::string&, const ParamMap&)
     */
    static AuthenticationPtr create(const std::string& pluginNameOrDynamicLibPath,
                                    const std::string& authParamsString);

    /**
     * Create an AuthenticationPtr
     *
     * When the first parameter represents the plugin name, the type of authentication can be one of the
     * following:
     * - AuthTls (if the plugin name is “tls”)
     * - AuthToken (if the plugin name is “token” or “org.apache.pulsar.client.impl.auth.AuthenticationToken”)
     * - AuthAthenz (if the plugin name is “athenz” or
     * “org.apache.pulsar.client.impl.auth.AuthenticationAthenz”)
     * - AuthOauth2 (if the plugin name is “oauth2token” or
     * “org.apache.pulsar.client.impl.auth.oauth2.AuthenticationOAuth2”)
     *
     * @param pluginNameOrDynamicLibPath the plugin name or the path or a dynamic library that contains the
     * implementation of Authentication
     * @param params the ParamMap that is passed to Authentication::create method
     */
    static AuthenticationPtr create(const std::string& pluginNameOrDynamicLibPath, ParamMap& params);

   protected:
    static bool isShutdownHookRegistered_;
    static std::vector<void*> loadedLibrariesHandles_;
    static void release_handles();
};

/**
 * TLS implementation of Pulsar client authentication
 */
class PULSAR_PUBLIC AuthTls : public Authentication {
   public:
    AuthTls(AuthenticationDataPtr&);
    ~AuthTls();

    /**
     * Create an AuthTls with a ParamMap
     *
     * It is equal to create(params[“tlsCertFile”], params[“tlsKeyFile”])
     * @see create(const std::string&, const std::string&)
     */
    static AuthenticationPtr create(ParamMap& params);

    /**
     * Create an AuthTls with an authentication parameter string
     *
     * @see Authentication::parseDefaultFormatAuthParams
     */
    static AuthenticationPtr create(const std::string& authParamsString);

    /**
     * Create an AuthTls with the required parameters
     *
     * @param certificatePath the file path for a client certificate
     * @param privateKeyPath the file path for a client private key
     */
    static AuthenticationPtr create(const std::string& certificatePath, const std::string& privateKeyPath);

    /**
     * @return “tls”
     */
    const std::string getAuthMethodName() const;

    /**
     * Get AuthenticationData from the current instance
     *
     * @param[out] authDataTls the shared pointer of AuthenticationData. The content of AuthenticationData is
     * changed to the internal data of the current instance.
     * @return ResultOk
     */
    Result getAuthData(AuthenticationDataPtr& authDataTls);

   private:
    AuthenticationDataPtr authDataTls_;
};

typedef std::function<std::string()> TokenSupplier;

/**
 * Token based implementation of Pulsar client authentication
 */
class PULSAR_PUBLIC AuthToken : public Authentication {
   public:
    AuthToken(AuthenticationDataPtr&);
    ~AuthToken();

    /**
     * Create an AuthToken with a ParamMap
     *
     * @param parameters it must contain a key-value, where key means how to get the token and value means the
     * token source
     *
     * If the key is “token”, the value is the token
     *
     * If the key is “file”, the value is the file that contains the token
     *
     * If the key is “env”, the value is the environment variable whose value is the token
     *
     * Otherwise, a `std::runtime_error` error is thrown.
     * @see create(const std::string& authParamsString)
     */
    static AuthenticationPtr create(ParamMap& params);

    /**
     * Create an AuthToken with an authentication parameter string
     *
     * @see Authentication::parseDefaultFormatAuthParams
     */
    static AuthenticationPtr create(const std::string& authParamsString);

    /**
     * Create an authentication provider for token based authentication
     *
     * @param token
     *            a string containing the auth token
     */
    static AuthenticationPtr createWithToken(const std::string& token);

    /**
     * Create an authentication provider for token based authentication
     *
     * @param tokenSupplier
     *            a supplier of the client auth token
     */
    static AuthenticationPtr create(const TokenSupplier& tokenSupplier);

    /**
     * @return “token”
     */
    const std::string getAuthMethodName() const;

    /**
     * Get AuthenticationData from the current instance
     *
     * @param[out] authDataToken the shared pointer of AuthenticationData. The content of AuthenticationData
     * is changed to the internal data of the current instance.
     * @return ResultOk
     */
    Result getAuthData(AuthenticationDataPtr& authDataToken);

   private:
    AuthenticationDataPtr authDataToken_;
};

/**
 * Basic based implementation of Pulsar client authentication
 */
class PULSAR_PUBLIC AuthBasic : public Authentication {
   public:
    explicit AuthBasic(AuthenticationDataPtr&);
    ~AuthBasic() override;

    /**
     * Create an AuthBasic with a ParamMap
     *
     * It is equal to create(params[“username”], params[“password”])
     * @see create(const std::string&, const std::string&)
     */
    static AuthenticationPtr create(ParamMap& params);

    /**
     * Create an AuthBasic with an authentication parameter string
     *
     * @param authParamsString the JSON format string: {"username": "admin", "password": "123456"}
     */
    static AuthenticationPtr create(const std::string& authParamsString);

    /**
     * Create an AuthBasic with the required parameters
     */
    static AuthenticationPtr create(const std::string& username, const std::string& password);

    /**
     * Create an AuthBasic with the required parameters
     */
    static AuthenticationPtr create(const std::string& username, const std::string& password,
                                    const std::string& method);

    /**
     * @return “basic”
     */
    const std::string getAuthMethodName() const override;

    /**
     * Get AuthenticationData from the current instance
     *
     * @param[out] authDataBasic the shared pointer of AuthenticationData. The content of AuthenticationData
     * is changed to the internal data of the current instance.
     * @return ResultOk
     */
    Result getAuthData(AuthenticationDataPtr& authDataBasic) override;

   private:
    AuthenticationDataPtr authDataBasic_;
};

/**
 * Athenz implementation of Pulsar client authentication
 */
class PULSAR_PUBLIC AuthAthenz : public Authentication {
   public:
    AuthAthenz(AuthenticationDataPtr&);
    ~AuthAthenz();

    /**
     * Create an AuthAthenz with a ParamMap
     *
     * The required parameter keys are “tenantDomain”, “tenantService”, “providerDomain”, “privateKey”, and
     * “ztsUrl”
     *
     * @param params the key-value to construct ZTS client
     * @see http://pulsar.apache.org/docs/en/security-athenz/
     */
    static AuthenticationPtr create(ParamMap& params);

    /**
     * Create an AuthAthenz with an authentication parameter string
     *
     * @see Authentication::parseDefaultFormatAuthParams
     */
    static AuthenticationPtr create(const std::string& authParamsString);

    /**
     * @return “athenz”
     */
    const std::string getAuthMethodName() const;

    /**
     * Get AuthenticationData from the current instance
     *
     * @param[out] authDataAthenz the shared pointer of AuthenticationData. The content of AuthenticationData
     * is changed to the internal data of the current instance.
     * @return ResultOk
     */
    Result getAuthData(AuthenticationDataPtr& authDataAthenz);

   private:
    AuthenticationDataPtr authDataAthenz_;
};

// OAuth 2.0 token and associated information.
// currently mainly works for access token
class Oauth2TokenResult {
   public:
    enum
    {
        undefined_expiration = -1
    };

    Oauth2TokenResult();
    ~Oauth2TokenResult();

    /**
     * Set the access token string
     *
     * @param accessToken the access token string
     */
    Oauth2TokenResult& setAccessToken(const std::string& accessToken);

    /**
     * Set the ID token
     *
     * @param idToken the ID token
     */
    Oauth2TokenResult& setIdToken(const std::string& idToken);

    /**
     * Set the refresh token which can be used to obtain new access tokens using the same authorization grant
     * or null for none
     *
     * @param refreshToken the refresh token
     */
    Oauth2TokenResult& setRefreshToken(const std::string& refreshToken);

    /**
     * Set the token lifetime
     *
     * @param expiresIn the token lifetime
     */
    Oauth2TokenResult& setExpiresIn(const int64_t expiresIn);

    /**
     * @return the access token string
     */
    const std::string& getAccessToken() const;

    /**
     * @return the ID token
     */
    const std::string& getIdToken() const;

    /**
     * @return the refresh token which can be used to obtain new access tokens using the same authorization
     * grant or null for none
     */
    const std::string& getRefreshToken() const;

    /**
     * @return the token lifetime in milliseconds
     */
    int64_t getExpiresIn() const;

   private:
    // map to json "access_token"
    std::string accessToken_;
    // map to json "id_token"
    std::string idToken_;
    // map to json "refresh_token"
    std::string refreshToken_;
    // map to json "expires_in"
    int64_t expiresIn_;
};

typedef std::shared_ptr<Oauth2TokenResult> Oauth2TokenResultPtr;

class Oauth2Flow {
   public:
    virtual ~Oauth2Flow();

    /**
     * Initializes the authorization flow.
     */
    virtual void initialize() = 0;

    /**
     * Acquires an access token from the OAuth 2.0 authorization server.
     * @return a token result including an access token.
     */
    virtual Oauth2TokenResultPtr authenticate() = 0;

    /**
     * Closes the authorization flow.
     */
    virtual void close() = 0;

   protected:
    Oauth2Flow();
};

typedef std::shared_ptr<Oauth2Flow> FlowPtr;

class CachedToken {
   public:
    virtual ~CachedToken();

    /**
     * @return true if the token has expired
     */
    virtual bool isExpired() = 0;

    /**
     * Get AuthenticationData from the current instance
     *
     * @return ResultOk or ResultAuthenticationError if authentication failed
     */
    virtual AuthenticationDataPtr getAuthData() = 0;

   protected:
    CachedToken();
};

typedef std::shared_ptr<CachedToken> CachedTokenPtr;

/**
 * Oauth2 based implementation of Pulsar client authentication.
 * Passed in parameter would be like:
 * ```
 *   "type": "client_credentials",
 *   "issuer_url": "https://accounts.google.com",
 *   "client_id": "d9ZyX97q1ef8Cr81WHVC4hFQ64vSlDK3",
 *   "client_secret": "on1uJ...k6F6R",
 *   "audience": "https://broker.example.com"
 *  ```
 *  If passed in as std::string, it should be in Json format.
 */
class PULSAR_PUBLIC AuthOauth2 : public Authentication {
   public:
    AuthOauth2(ParamMap& params);
    ~AuthOauth2();

    /**
     * Create an AuthOauth2 with a ParamMap
     *
     * The required parameter keys are “issuer_url”, “private_key”, and “audience”
     *
     * @param parameters the key-value to create OAuth 2.0 client credentials
     * @see http://pulsar.apache.org/docs/en/security-oauth2/#client-credentials
     */
    static AuthenticationPtr create(ParamMap& params);

    /**
     * Create an AuthOauth2 with an authentication parameter string
     *
     * @see Authentication::parseDefaultFormatAuthParams
     */
    static AuthenticationPtr create(const std::string& authParamsString);

    /**
     * @return “token”
     */
    const std::string getAuthMethodName() const;

    /**
     * Get AuthenticationData from the current instance
     *
     * @param[out] authDataOauth2 the shared pointer of AuthenticationData. The content of AuthenticationData
     * is changed to the internal data of the current instance.
     * @return ResultOk or ResultAuthenticationError if authentication failed
     */
    Result getAuthData(AuthenticationDataPtr& authDataOauth2);

   private:
    FlowPtr flowPtr_;
    CachedTokenPtr cachedTokenPtr_;
};

}  // namespace pulsar

#endif /* PULSAR_AUTHENTICATION_H_ */
