#pragma once

#include <cstdint>
#include <filesystem>
#include <string>
#include <vector>

namespace smartcut::core {

struct EntitlementPublicKey {
  std::vector<std::uint8_t> modulus;
  std::vector<std::uint8_t> exponent;
};

enum class EntitlementState {
  paid,
  missing,
  malformed,
  unsupported_platform,
  no_verification_key,
  invalid_signature,
  wrong_product,
  wrong_edition,
  wrong_installation,
  not_yet_valid,
  expired
};

struct EntitlementResult {
  EntitlementState state = EntitlementState::missing;
  std::string license_id;
  std::string customer;
  std::int64_t issued_unix = 0;
  std::int64_t not_before_unix = 0;
  std::int64_t expires_unix = 0;
  std::string installation_id;
  std::string detail;

  [[nodiscard]] bool paid() const { return state == EntitlementState::paid; }
};

// SmartCut64 entitlement tokens are signed, compact text files. The private
// signing key is never distributed with the application or source tree.
EntitlementResult verify_entitlement(const std::string& token,
                                     const EntitlementPublicKey& public_key,
                                     std::int64_t now_unix);
EntitlementResult verify_entitlement(const std::string& token,
                                     const EntitlementPublicKey& public_key,
                                     std::int64_t now_unix,
                                     const std::string& installation_id);
EntitlementResult verify_entitlement(const std::string& token,
                                     std::int64_t now_unix);
EntitlementPublicKey compiled_entitlement_public_key();
std::string current_installation_id();
std::filesystem::path default_entitlement_path();
std::filesystem::path installed_entitlement_path();
std::string load_installed_entitlement_token();
EntitlementResult verify_installed_entitlement(std::int64_t now_unix);
const char* entitlement_state_name(EntitlementState state);

}  // namespace smartcut::core
