/**
 * 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/defines.h>
#include <vector>
#include <string>
#include <map>
#include <memory>
#include <pulsar/Result.h>
#include <functional>

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);

    /**
     * @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_ */
