/*
 This file is part of GNU Taler
 (C) 2019 GNUnet e.V.

 GNU Taler is free software; you can redistribute it and/or modify it under the
 terms of the GNU General Public License as published by the Free Software
 Foundation; either version 3, or (at your option) any later version.

 GNU Taler 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 General Public License for more details.

 You should have received a copy of the GNU General Public License along with
 GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
 */

import test from "ava";

import { HostPortPath, PaytoType, Paytos } from "./payto.js";
import { succeedOrThrow } from "./index.js";

test("basic payto parsing", (t) => {
  const r1 = Paytos.fromString("https://example.com/");
  t.is(r1.type, "fail");

  const r2 = Paytos.fromString("payto:blabla");
  t.is(r2.type, "fail");

  // this doesn't work because x-taler-bank requires host and account
  const r3 = Paytos.fromString("payto:://x-taler-bank/12");
  t.is(r3.type, "fail");

  const r4 = Paytos.fromString("payto://x-taler-bank/host/account");
  if (r4.type === "fail") {
    t.fail();
    throw Error();
  }
  if (r4.body.targetType !== PaytoType.TalerBank) {
    t.fail(r4.body.targetType);
    throw Error();
  }
  t.is(r4.body.normalizedPath, "host/account");
});

test("basic x-taler-bank payto string", (t) => {
  const result = succeedOrThrow(
    Paytos.fromString("payto://x-taler-bank/bank.demo.taler.net/accountName"),
  );

  if (result.targetType !== PaytoType.TalerBank) {
    t.fail();
    throw Error();
  }
  t.is(result.normalizedPath, "bank.demo.taler.net/accountName");
  t.is(result.host, "bank.demo.taler.net");
  t.is(result.url, "https://bank.demo.taler.net/" as HostPortPath);
  t.is(result.account, "accountName");
});

test("parsing payto and stringify again on normalized strings are unchanged", (t) => {
  const payto1 = "payto://iban/DE1231231231?reciever-name=John%20Doe";
  t.is(
    Paytos.toFullString(succeedOrThrow(Paytos.fromString(payto1))),
    payto1 as Paytos.FullPaytoString,
  );

  const normalized = "payto://iban/DE1231231231";
  t.is(
    Paytos.toNormalizedString(succeedOrThrow(Paytos.fromString(payto1))),
    normalized as Paytos.NormalizedPaytoString,
  );
});
test("parsing payto and stringify again converts to the normal form", (t) => {
  const fullPayto_not_normalized = "payto://iban/de1231231231?reciever-name=John%20Doe";
  // after normalization the country code is uppercased
  const fullPayto_normalized = "payto://iban/DE1231231231?reciever-name=John%20Doe" as Paytos.FullPaytoString;
  t.is(
    Paytos.toFullString(succeedOrThrow(Paytos.fromString(fullPayto_not_normalized))),
    fullPayto_normalized,
  );

  const normalized_lowercase = "payto://iban/DE1231231231";
  const normalized_uppercase = "payto://iban/DE1231231231" as Paytos.NormalizedPaytoString;
  t.is(
    Paytos.toNormalizedString(succeedOrThrow(Paytos.fromString(normalized_lowercase))),
    normalized_uppercase,
  );
});
test("parsing payto with % carh", (t) => {
  const payto1 =
    "payto://iban/DE7763544441436?receiver-name=Test%20123%2B-%24%25%5E%3Cem%3Ehi%3C%2Fem%3E" as Paytos.FullPaytoString;

  t.is(Paytos.toFullString(succeedOrThrow(Paytos.fromString(payto1))), payto1);
});

test("adding payto query params", (t) => {
  const payto1 =
    "payto://iban/DE1231231231?receiver-name=John%20Doe" as Paytos.FullPaytoString;
  const p = succeedOrThrow(Paytos.fromString(payto1));

  p.params["foo"] = "42";
  
  t.deepEqual(
    Paytos.toFullString(p),
    "payto://iban/DE1231231231?receiver-name=John%20Doe&foo=42",
  );
});
