let () =
  let open Json in
  let check jsont s =
    let encode v = encode jsont v |> Result.get_ok in
    let decode v = decode jsont v |> Result.get_ok in
    let ts = decode s in
    let s' = encode ts in
    let ts' = decode s' in
    let s'' = encode ts' in
    assert (String.equal s' s'')
  in
  let check_bad jsont s =
    let decode = decode jsont in
    assert (Result.is_error (decode s))
  in
  check Timestamp.jsont {|{"t_s": 123456780}|};
  check Timestamp.jsont {|{"t_s": "never"}|};
  check_bad Timestamp.jsont {|{"t_s": "123456780"}|};
  check_bad Timestamp.jsont {|{"t_s": "agagou"}|};

  (* TODO use a valid rsa_pub value *)
  (*
  check DenominationKey.jsont
    {|{"cipher": "RSA", "age_mask": 18, "rsa_pub": "agagouh"}|};
  check DenominationKey.jsont
    {|{"cipher": "CS", "age_mask": 18, "cs_pub": "ouhagag"}|};
    *)
  ()

let () =
  let open Types.Amount in
  let v =
    {
      sign= Some `Plus;
      currency= `Eur;
      value= Int64.of_int 25;
      fraction= Int64.of_int 678;
    }
  in
  let s = to_string v in
  let v' = of_string s |> Result.get_ok in
  assert (v = v');
  let r = of_string {|~EUR:4.9|} in
  assert (Result.is_error r);
  let r = of_string {|+EUR:4.99999999999999999999999|} in
  assert (Result.is_error r);
  ()

let () =
  let open Headers_lib.Etag in
  let check input = assert (Result.is_ok (parse input)) in
  let check_bad input = assert (Result.is_error (parse input)) in

  check "*";
  check "\"foo\"";
  check "W/\"foo\"";
  check "\"foo\", \"bar\"";
  check " W/\"x\" , W/\"y\" , \"z\" ";
  check "  \"one\" ,  \"two\"  ,  \"three\"  ";
  check "W/\"a\"";
  check "  W/\"a\" , \"b\"";

  check_bad "";
  check_bad "foo";
  check_bad "W/foo";
  check_bad "W/\"unterminated";
  check_bad "\"foo\", W/";
  check_bad "* , \"bar\"";
  check_bad "\"a\" \"b\"";
  check_bad "W/\"a\" W/\"b\"";
  check_bad "\"fo\x7Fo\"";

  (* TODO trailing comma are valid actually, I think *)
  check_bad "\"foo\" ,";
  check_bad ", \"foo\"";
  ()

(*

let () =
  let open Binary_formats.WithdrawConfirmationPS in
  let str64 = String.init 64 (fun i -> Char.unsafe_chr (i + 1)) in
  let dummy_t = { h_planchets= { hash= str64 }; noreveal_index= 0_l } in
  let size = Bin.size_of_value bin dummy_t |> Option.get in
  assert (size = 76);

  (* for cmp test with signatures.c output *)
  (*
  let raw_str = Bin.to_string bin dummy_t in
  Printf.printf "%s" raw_str;
  *)
  ()

  *)
