package peergos.shared.storage;

import jsinterop.annotations.*;
import peergos.shared.cbor.*;

import java.util.*;

public final class PaymentProperties  implements Cborable {

    public final Optional<String> paymentServerUrl;
    public final Optional<String> clientSecret;
    public final long freeQuota;
    public final long desiredQuota;

    private PaymentProperties(Optional<String> paymentServerUrl, Optional<String> clientSecret, long freeQuota, long desiredQuota) {
        this.paymentServerUrl = paymentServerUrl;
        this.clientSecret = clientSecret;
        this.freeQuota = freeQuota;
        this.desiredQuota = desiredQuota;
    }

    public PaymentProperties(long freeQuota) {
        this(Optional.empty(), Optional.empty(), freeQuota, 0);
    }

    public PaymentProperties(String paymentServerUrl, Optional<String> clientSecret, long freeQuota, long desiredQuota) {
        this(Optional.of(paymentServerUrl), clientSecret, freeQuota, desiredQuota);
    }

    @JsMethod
    public boolean isPaid() {
        return paymentServerUrl.isPresent();
    }

    @JsMethod
    public String getUrl() {
        return paymentServerUrl.get();
    }

    @JsMethod
    public String getClientSecret() {
        return clientSecret.orElse("");
    }

    @Override
    public CborObject toCbor() {
        SortedMap<String, Cborable> state = new TreeMap<>();
        state.put("freeQuota", new CborObject.CborLong(desiredQuota));
        state.put("desiredQuota", new CborObject.CborLong(desiredQuota));
        paymentServerUrl.ifPresent(url -> state.put("url", new CborObject.CborString(url)));
        if (clientSecret.isPresent())
            state.put("client_secret", new CborObject.CborString(clientSecret.get()));
        return CborObject.CborMap.build(state);
    }

    public static PaymentProperties fromCbor(Cborable cbor) {
        if (! (cbor instanceof CborObject.CborMap))
            throw new IllegalStateException("Invalid cbor for FileProperties! " + cbor);
        CborObject.CborMap m = (CborObject.CborMap) cbor;
        Optional<String> url = m.getOptional("url", c -> ((CborObject.CborString)c).value);
        Optional<String> client_secret = m.getOptional("client_secret", c -> ((CborObject.CborString) c).value);
        long freeQuota = m.getLong("freeQuota");
        long desiredQuota = m.getLong("desiredQuota");
        return new PaymentProperties(url, client_secret, freeQuota, desiredQuota);
    }
}

@@ -267,24 +267,65 @@
 ientSecret;%0A
+    public final Optional%3CString%3E error;%0A
     public f
@@ -450,55 +450,199 @@
 Url,
- Optional%3CString%3E clientSecret, long freeQuota,
+%0A                              Optional%3CString%3E error,%0A                              Optional%3CString%3E clientSecret,%0A                              long freeQuota,%0A                             
  lon
@@ -705,24 +705,52 @@
 tServerUrl;%0A
+        this.error = error;%0A
         this
@@ -959,16 +959,34 @@
 empty(),
+ Optional.empty(),
  freeQuo
@@ -1165,16 +1165,34 @@
 verUrl),
+ Optional.empty(),
  clientS
@@ -1319,32 +1319,199 @@
 esent();%0A    %7D%0A%0A
+    @JsMethod%0A    public boolean hasError() %7B%0A        return error.isPresent();%0A    %7D%0A%0A    @JsMethod%0A    public String getError() %7B%0A        return error.get();%0A    %7D%0A%0A
     @JsMethod%0A  
@@ -1678,24 +1678,486 @@
 %22%22);%0A    %7D%0A%0A
+    public static PaymentProperties errored(String paymentServerUrl,%0A                                            String error,%0A                                            Optional%3CString%3E clientSecret,%0A                                            long freeQuota,%0A                                            long desiredQuota) %7B%0A        return new PaymentProperties(Optional.of(paymentServerUrl), Optional.of(error), clientSecret, freeQuota, desiredQuota);%0A    %7D%0A%0A
     @Overrid
@@ -2486,24 +2486,106 @@
 ing(url)));%0A
+        error.ifPresent(err -%3E state.put(%22err%22, new CborObject.CborString(err)));%0A
         if (
@@ -3097,32 +3097,124 @@
 ring)c).value);%0A
+        Optional%3CString%3E err = m.getOptional(%22err%22, c -%3E ((CborObject.CborString)c).value);%0A
         Optional
@@ -3455,16 +3455,21 @@
 ies(url,
+ err,
  client_

Add error to payment properties