(**************************************************************************)
(*                                BELENIOS                                *)
(*                                                                        *)
(*  Copyright © 2012-2020 Inria                                           *)
(*                                                                        *)
(*  This program is free software: you can redistribute it and/or modify  *)
(*  it under the terms of the GNU Affero General Public License as        *)
(*  published by the Free Software Foundation, either version 3 of the    *)
(*  License, or (at your option) any later version, with the additional   *)
(*  exemption that compiling, linking, and/or using OpenSSL is allowed.   *)
(*                                                                        *)
(*  This program is distributed in the hope that it will be useful, but   *)
(*  WITHOUT ANY WARRANTY; without even the implied warranty of            *)
(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *)
(*  Affero General Public License for more details.                       *)
(*                                                                        *)
(*  You should have received a copy of the GNU Affero General Public      *)
(*  License along with this program.  If not, see                         *)
(*  <http://www.gnu.org/licenses/>.                                       *)
(**************************************************************************)

<doc text="Web-specific serializable datatypes">

(** {1 Predefined types} *)

type number <ocaml predef from="Belenios.Serializable_builtin"> = abstract
type uuid <ocaml predef from="Belenios.Serializable_builtin"> = abstract
type datetime <ocaml predef from="Web_serializable_builtin"> = abstract
type proof <ocaml predef from="Belenios.Serializable"> = abstract
type template <ocaml predef from="Belenios.Serializable"> = abstract
type election_checksums <ocaml predef from="Belenios.Serializable"> = abstract
type cert <ocaml predef from="Belenios.Serializable"> = abstract
type polynomial <ocaml predef from="Belenios.Serializable"> = abstract
type vinput <ocaml predef from="Belenios.Serializable"> = abstract

(** {1 Web-specific types} *)

type user = {
  domain : string;
  name : string;
} <ocaml field_prefix="user_">

type auth_config = {
  auth_system : string;
  auth_instance : string;
  auth_config : (string * string) list;
}

type metadata = {
  ?owner: user option;
  ?auth_config: auth_config list option;
  ?cred_authority : string option;
  ?trustees : string list option;
  ?languages : string list option;
  ?contact : string option;
  ?server_is_trustee : bool option;
} <ocaml field_prefix="e_">

type election_dates = {
  ?creation : datetime option;
  ?finalization : datetime option;
  ?tally : datetime option;
  ?archive : datetime option;
  ?last_mail : datetime option;
  ?auto_open : datetime option;
  ?auto_close : datetime option;
} <ocaml field_prefix="e_">

type extended_record = {
  username : string;
  date : datetime;
  credential : string;
} <ocaml field_prefix="r_">

type credential_mapping = {
  credential : string;
  ?ballot : string option;
} <ocaml field_prefix="c_">

type election_state =
  [ Open
  | Closed
  | Shuffling
  | EncryptedTally of (int * int * string)
  | Tallied
  | Archived
  ]

type partial_decryptions = (int * string) list
type decryption_tokens = string list

(* The following is a supertype of trustee_public_key *)
type 'a web_trustee_public_key = {
  pok : proof;
  public_key : 'a;
  ?server : bool option;
} <ocaml field_prefix="web_trustee_">

type audit_cache = {
  num_voters : int;
  ?total_weight : int option;
  ?min_weight : int option;
  ?max_weight : int option;
  voters_hash : string;
  checksums : election_checksums;
  ?threshold : int option;
} <ocaml field_prefix="cache_">

(** {1 Types related to elections being prepared} *)

type draft_voter = {
  id : string;
  ?password <ocaml mutable> : (string * string) option;
} <ocaml field_prefix="sv_">

type draft_trustee = {
  id : string;
  token : string;
  public_key <ocaml mutable> : string;
  ?private_key : number option;
  ?name : string option;
} <ocaml field_prefix="st_">

type draft_threshold_trustee = {
  id : string;
  token : string;
  ?step <ocaml mutable> : int option;
  ?cert <ocaml mutable> : cert option;
  ?polynomial <ocaml mutable> : polynomial option;
  ?vinput <ocaml mutable> : vinput option;
  ?voutput <ocaml mutable> : string option;
  ?name : string option;
} <ocaml field_prefix="stt_">

type draft_election = {
  owner : user;
  group <ocaml mutable> : string;
  voters <ocaml mutable> : draft_voter list;
  questions <ocaml mutable> : template;
  public_keys <ocaml mutable> : draft_trustee list;
  metadata <ocaml mutable> : metadata;
  public_creds : string;
  public_creds_received <ocaml mutable> : bool;
  ?threshold <ocaml mutable> : int option;
  ?threshold_trustees <ocaml mutable> : draft_threshold_trustee list option;
  ?threshold_parameters <ocaml mutable> : string option;
  ?threshold_error <ocaml mutable> : string option;
  ?creation_date : datetime option;
  ?administrator <ocaml mutable> : string option;
} <ocaml field_prefix="se_">

(** {1 Types related to elections being tallied} *)

type shuffle_hash = {
    trustee : string;
    hash : string;
    ?name : string option;
} <ocaml field_prefix="sh_">

type shuffle_token = {
    trustee : string;
    token : string;
    ?name : string option;
} <ocaml field_prefix="tk_">

(** {1 Types related to deleted elections} *)

type authentication_method = [ CAS of string | Password | Unknown ]
type credential_method = [ Automatic | Manual ]

type deleted_trustee = [ Single | Pedersen of (int * int) ]

type deleted_election = {
  uuid : uuid;
  template : template;
  owner : user;
  nb_voters : int;
  nb_ballots : int;
  date : datetime;
  tallied : bool;
  authentication_method : authentication_method;
  credential_method : credential_method;
  trustees : deleted_trustee list;
  server_is_trustee : bool;
} <ocaml field_prefix="de_">

(** {1 OpenID Connect-related types} *)

type oidc_configuration = {
  authorization_endpoint : string;
  token_endpoint : string;
  userinfo_endpoint : string;
}

type oidc_tokens = {
  access_token : string;
  token_type : string;
  id_token : string;
} <ocaml field_prefix="oidc_">

type oidc_userinfo = {
  sub : string;
  ?email : string option;
} <ocaml field_prefix="oidc_">
