// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package io.v.v23.security;

import com.google.common.base.Joiner;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.security.interfaces.ECPublicKey;
import java.util.ArrayList;
import java.util.List;

import io.v.v23.verror.VException;

/**
 * Encapsulator of all the cryptographic operations required to prove that a set of blessings
 * (human-readable strings) have been bound to a principal in a specific call.
 * <p>
 * {@link Blessings} objects are meant to be presented to other principals to authenticate
 * and authorize actions.  Functions {@link VSecurity#getLocalBlessingNames} and
 * {@link VSecurity#getRemoteBlessingNames} can be used to uncover the blessing names encapsulated
 * in these objects.
 * <p>
 * {@link Blessings} objects are immutable and multiple threads may invoke methods on
 * them simultaneously.
 * <p>
 * See also: <a href="https://github.com/vanadium/docs/blob/master/glossary.md#blessing">https://github.com/vanadium/docs/blob/master/glossary.md#blessing</a>.
 */
public final class Blessings implements Serializable {
    private static final long serialVersionUID = 1L;

    private static native long nativeCreate(WireBlessings wire) throws VException;
    private static native Blessings nativeCreateUnion(Blessings[] blessings) throws VException;

    public static Blessings create(WireBlessings wire) {
        try {
            return new Blessings(nativeCreate(wire), wire);
        } catch (VException e) {
            throw new RuntimeException("Couldn't create blessings from WireBlessings", e);
        }
    }

    static Blessings createUnion(Blessings... blessings) throws VException {
        return nativeCreateUnion(blessings);
    }

    private long nativePtr;
    private volatile WireBlessings wire;  // can be null

    private native ECPublicKey nativePublicKey(long nativePtr) throws VException;
    private native Blessings nativeSigningBlessings(long nativePtr) throws VException;
    private native WireBlessings nativeWireFormat(long nativePtr) throws VException;

    private native void nativeFinalize(long nativePtr);

    private Blessings(long nativePtr) {
        this.nativePtr = nativePtr;
    }

    private Blessings(long nativePtr, WireBlessings wire) {
        this.nativePtr = nativePtr;
        this.wire = wire;
    }

    /**
     * Returns the public key of the principal to which blessings in this object are bound.
     * The return value may be {@code null} if the blessings are empty.
     */
    public ECPublicKey publicKey() {
        try {
            return nativePublicKey(nativePtr);
        } catch (VException e) {
            throw new RuntimeException("Couldn't get public key", e);
        }
    }

    /**
     * Returns the signing blessings in this object. (Signing blessings are blessings whose
     * caveats are universally understood and verifiable without third party discharges.)
     * The return value may be {@code null} if the blessings are empty.
     */
    public Blessings signingBlessings() {
        try {
            return nativeSigningBlessings(nativePtr);
      } catch (VException e) {
          throw new RuntimeException("Couldn't get signing blessings", e);
      }
    }

    /**
     * Returns the blessings in the wire format.
     */
    public WireBlessings wireFormat() {
        // Check the cache first as nativeWireFormat() is an expensive operation.
        synchronized (this) {
            if (wire != null) {
                return wire;
            }
        }
        WireBlessings ret = null;
        try {
            ret = nativeWireFormat(nativePtr);
        } catch (VException e) {
            throw new RuntimeException("Couldn't get wire blessings representation.", e);
        }
        synchronized (this) {
            if (wire == null) {
                wire = ret;
            }
        }
        return ret;
    }

    /**
     * Returns {@code true} iff the blessings are empty.
     */
    public boolean isEmpty() {
        return wireFormat().getCertificateChains().isEmpty();
    }

    /**
     * Returns the certificate chains stored inside the blessings.
     */
    public List<List<VCertificate>> getCertificateChains() {
        return wireFormat().getCertificateChains();
    }

    private long nativePtr() {
        return nativePtr;
    }

    private void writeObject(ObjectOutputStream out) throws IOException {
        out.writeObject(wireFormat());
    }

    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        wire = (WireBlessings) in.readObject();
        try {
            nativePtr = nativeCreate(wire);
        } catch (VException e) {
            throw new IOException("Couldn't create native blessings.", e);
        }
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null) return false;
        if (!(obj instanceof Blessings)) return false;
        Blessings other = (Blessings) obj;
        return wireFormat().equals(other.wireFormat());
    }

    @Override
    public int hashCode() {
        return wireFormat().hashCode();
    }

    @Override
    public String toString() {
        List<String> chains = new ArrayList<String>(getCertificateChains().size());
        for (List<VCertificate> certificateChain : getCertificateChains()) {
            List<String> certificateNames =
                    new ArrayList<String>(certificateChain.size());
            for (VCertificate certificate : certificateChain) {
                certificateNames.add(certificate.getExtension());
            }
            chains.add(Joiner.on("/").join(certificateNames));
        }
        return Joiner.on(",").join(chains);
    }
    @Override
    protected void finalize() {
        nativeFinalize(nativePtr);
    }
}
