(* https://docs.taler.net/manpages/taler-exchange.conf.5.html
   taler-docs/manpages/taler-exchange.conf.5.rst *)
(* TODO
   - generate `config.ml` from config file (virtual module)?
   - parse config file format
   - no relative path
   - default config
   - better types
   - impl duration
   *)

(* TODO unikernel *)
type dir_path
type file_path

(* TODO *)
(* Values that represent a time duration are represented as a series of one or more NUMBER UNIT pairs, e.g. 60 s, 4 weeks 1 day, 5 years 2 minutes. *)
type duration

(* TODO
   make it Amount.t *)
type amount = string
type payto_uri = string

(* TODO
   still need to parse them and tell that its not supported
   some maybe are relevant
   idk *)
type not_relevant
type url = string
type seconds = int

(* not relevant for mirage *)
(* this contains path that can be referenced in other with $PATH
   (unsupported) *)
module type Global = sig
  val taler_home : dir_path
  val taler_data_home : dir_path
  val taler_config_home : dir_path
  val taler_cache_home : dir_path
  val taler_runtime_dir : dir_path
end

(* sections "[currency-$NAME]"
   see DD51 *)
module type Currency = sig
  val enabled : [ `YES | `NO ]
  val code : string
  val name : string
  val fractional_input_digits : int
  val fractional_normal_digits : int
  val fractional_trailing_zero_digits : int
  val alt_unit_names : (int * string) list
end

(* section "[exchange]" *)
module type Exchange = sig
  val currency : string
  val currency_round_unit : amount
  val db : string
  val attribute_encryption_key : string
  val serve : [ `Unix | `Tcp | `Systemd ]
  val unixpath : file_path
  val unixpath_mode : int
  val port : int
  val bind_to : string
  val master_public_key : string
  val tiny_amount : amount option
  val shopping_url : url option
  val open_banking_gateway_url : url option
  val aml_spa_dialect : string option
  val bank_compliance_language : string option
  val stefan_abs : amount
  val stefan_log : amount
  val stefan_lin : float
  val base_url : url
  val toplevel_redirect_url : string option
  val aggregator_idle_sleep_interval : seconds
  val closer_idle_sleep_interval : seconds
  val transfer_idle_sleep_interval : seconds
  val wirewatch_idle_sleep_interval : seconds
  val aggregator_shard_size : int option
  val signkey_legal_duration : duration
  val max_keys_caching : duration
  val max_requests : int
  val terms_dir : dir_path
  val terms_etag : string
  val privacy_dir : dir_path
  val privacy_etag : string
  val enable_kyc : [ `YES | `NO ]
end

(* section "[taler-exchange-secmod-{rsa|cs|eddsa}]". *)
module type Secmod = sig
  val lookahead_sign : duration
  val overlap_duration : duration
  val sm_priv_key : file_path
  val key_dir : dir_path
  val unixpath : not_relevant
end

module type Secmod_rsa = Secmod
module type Secmod_cs = Secmod
module type Secmod_eddsa = Secmod

(* TODO config
   what is the time/duration unit used here? *)
(* section "[exchangedb]". *)
module type Database = sig
  val idle_reserve_expiration_time : seconds
  val legal_reserve_expiration_time : seconds
  val aggregator_shift : seconds
  val default_purse_limit : int
  val max_aml_program_runtime : int option

  module type Postgres_backend = sig
    val config : string
  end
end

(* sections "[coin_XXX]"
   used by secmods *)
module type Coin = sig
  val value : amount
  val duration_withdraw : duration
  val duration_spend : duration
  val duration_legal : duration
  val fee_withdraw : amount
  val fee_deposit : amount
  val fee_refresh : amount
  val fee_refund : amount
  val cipher : [ (* `CS |*) `RSA ]
  val rsa_keysize : int option (*only if `RSA *)
  val age_restricted : [ (*`YES|*) `NO ]
end

(* sections "[exchange-account-XXX]" *)
module type Account = sig
  val payto_uri : payto_uri
  val enable_debit : [ `YES | `NO ]
  val enable_credit : [ `YES | `NO ]
end

(* sections "[exchange-accountcredentials-XXX]"
   must exists for each "[exchange-account-XXX]" section

   ! credentials to access the bank account
   should be in a secret configuration file
   only redable for `taler-exchange-wirewatch` `taler-exchange-transfer` processes *)
module type Account_secret = sig
  val wire_gateway_url : url
  val wire_gateway_auth_method : string
  val username : string
  val password : string
  val token : string
end

(* section "[exchange-extension-<extensionname>]" *)
module type Extensions = sig
  val enabled : [ (*`YES|*) `NO ]
end

(* section "[exchange-offline]". *)
module type Offline_signing = sig
  val master_priv_file : file_path

  (* TODO
   - we need two different file here
   - there is three, not two, crypto helper modules
     is it only two, because the eddsa one is not comptabilized as a "crypto helper" here? *)
  (* tofu = Trust On First Use *)
  val secm_tofu_file : file_path
  val secm_denom_pubkey : string option
  val secm_esign_pubkey : string option
end
