#pragma once

#ifndef GEODE_DIFFIEHELLMAN_H_
#define GEODE_DIFFIEHELLMAN_H_

/*
 * 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 <string>

#include <ace/DLL.h>

#include <geode/CacheableBuiltins.hpp>
#include <geode/Properties.hpp>

#define DH_ERR_NO_ERROR 0
#define DH_ERR_UNSUPPORTED_ALGO 1
#define DH_ERR_ILLEGAL_KEYSIZE 2
#define DH_ERR_SUBJECT_NOT_FOUND 3
#define DH_ERR_NO_CERTIFICATES 4
#define DH_ERR_INVALID_SIGN 5

const char SecurityClientDhAlgo[] = "security-client-dhalgo";
const char SecurityClientKsPath[] = "security-client-kspath";

namespace apache {
namespace geode {
namespace client {

class DiffieHellman {
 public:
  void initDhKeys(const std::shared_ptr<Properties>& props);
  void clearDhKeys(void);
  std::shared_ptr<CacheableBytes> getPublicKey(void);
  void setPublicKeyOther(const std::shared_ptr<CacheableBytes>& pubkey);
  void computeSharedSecret(void);
  std::shared_ptr<CacheableBytes> encrypt(
      const std::shared_ptr<CacheableBytes>& cleartext);
  std::shared_ptr<CacheableBytes> encrypt(const uint8_t* cleartext, int len);
  std::shared_ptr<CacheableBytes> decrypt(
      const std::shared_ptr<CacheableBytes>& cleartext);
  std::shared_ptr<CacheableBytes> decrypt(const uint8_t* cleartext, int len);
  bool verify(const std::shared_ptr<CacheableString>& subject,
              const std::shared_ptr<CacheableBytes>& challenge,
              const std::shared_ptr<CacheableBytes>& response);

  static void initOpenSSLFuncPtrs();

  DiffieHellman() : m_dhCtx(nullptr) {}

 private:
  void* m_dhCtx;
  static void* getOpenSSLFuncPtr(const char* function_name);

  // OpenSSL Func Ptrs: Declare Func Ptr type and a static variable of
  // std::shared_ptr<Func> type. Convention: <Orig Func Name>_Type and <Orig
  // Func Name>_Ptr
  typedef int (*gf_initDhKeys_Type)(void** dhCtx, const char* dhAlgo,
                                    const char* ksPath);
  typedef void (*gf_clearDhKeys_Type)(void* dhCtx);
  typedef unsigned char* (*gf_getPublicKey_Type)(void* dhCtx, int* len);
  typedef void (*gf_setPublicKeyOther_Type)(void* dhCtx,
                                            const unsigned char* pubkey,
                                            int length);
  typedef void (*gf_computeSharedSecret_Type)(void* dhCtx);
  typedef unsigned char* (*gf_encryptDH_Type)(void* dhCtx,
                                              const unsigned char* cleartext,
                                              int len, int* retLen);
  typedef unsigned char* (*gf_decryptDH_Type)(void* dhCtx,
                                              const unsigned char* cleartext,
                                              int len, int* retLen);
  typedef bool (*gf_verifyDH_Type)(void* dhCtx, const char* subject,
                                   const unsigned char* challenge,
                                   int challengeLen,
                                   const unsigned char* response,
                                   int responseLen, int* reason);

#define DECLARE_DH_FUNC_PTR(OrigName) static OrigName##_Type OrigName##_Ptr;

  DECLARE_DH_FUNC_PTR(gf_initDhKeys)
  DECLARE_DH_FUNC_PTR(gf_clearDhKeys)
  DECLARE_DH_FUNC_PTR(gf_getPublicKey)
  DECLARE_DH_FUNC_PTR(gf_setPublicKeyOther)
  DECLARE_DH_FUNC_PTR(gf_computeSharedSecret)
  DECLARE_DH_FUNC_PTR(gf_encryptDH)
  DECLARE_DH_FUNC_PTR(gf_decryptDH)
  DECLARE_DH_FUNC_PTR(gf_verifyDH)

  static ACE_DLL m_dll;

};  // class DiffieHellman
}  // namespace client
}  // namespace geode
}  // namespace apache

#endif  // GEODE_DIFFIEHELLMAN_H_
