// Copyright 2016 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.android.libs.inspectors;

import android.util.Base64;
import android.util.Log;

import com.google.common.collect.ImmutableList;

import org.joda.time.DateTime;
import org.joda.time.ReadableDuration;

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.ECPublicKey;
import java.util.List;

import io.v.android.v23.V;
import io.v.v23.context.VContext;
import io.v.v23.naming.Endpoint;
import io.v.v23.rpc.ListenSpec;
import io.v.v23.security.Blessings;
import io.v.v23.security.Caveat;
import io.v.v23.security.VPrincipal;
import io.v.v23.security.VSecurity;
import io.v.v23.security.access.Tag;
import io.v.v23.verror.VException;
import io.v.v23.vom.VomUtil;

/**
 * A RemoteInspectors object creates and manages a secure network server that allows authorized
 * remote users to inspect the (Vanadium-specific) state of the application such as statistics,
 * and log files.
 *
 * <p>When a remote user is invited via the {@link #invite(String, ReadableDuration)} method, a
 * principal and blessing is generated that is suitable for use by the
 * <a href="https://godoc.org/v.io/x/ref/services/debug/debug">{@code debug browse}</a> command.
 * The blessing allows only for debug access and thus does not grant the remote user any access to
 * change application state (techinically, does not allow them to invoke any method not tagged with
 * {@link io.v.v23.security.access.Constants#DEBUG}).
 */
public class RemoteInspectors {
    private static final String TAG = "RemoteInspectors";
    private static final int BASE64_FLAGS = Base64.URL_SAFE | Base64.NO_WRAP;
    private VContext mCtx;
    private String mMountedName;

    /**
     * Creates a secure network server to expose application state to invited remote users.
     *
     * @param ctx the Vanadium context of the application whose state is to be exposed
     * @throws VException
     */
    public RemoteInspectors(VContext ctx) throws VException {
        mCtx = ctx.withCancel();
        try {
            mMountedName = createMountedName(ctx);
        } catch (NoSuchAlgorithmException e) {
            throw new VException("Unable to create mounted name:" + e);
        }
        Log.i(TAG, "Application state should be inspectable via: " + mMountedName);
        mCtx = V.withNewServer(
                V.withListenSpec(mCtx, new ListenSpec("tcp", ":0").withProxy("proxy")),
                mMountedName,
                new InspectedServer() {},
                VSecurity.newDefaultAuthorizer());
    }

    /**
     * Invite a remote user to inspect state of the application.
     *
     * @param invitee the name to refer to the remote user as (typically an email address)
     * @param duration time after which inspection privileges expire
     *
     * @return A textual description of how the remote user can access state of the running
     * application.
     */
    public synchronized String invite(String invitee, ReadableDuration duration)
        throws  VException {
        if (mCtx == null) {
            throw new VException("RemoteInspectors.stop already called");
        }

        // In sync with the "debug delegate" command in
        // v.io/x/ref/services/debug/debug/browse.go
        List<Tag> tags = ImmutableList.of(
                io.v.v23.security.access.Constants.DEBUG,
                io.v.v23.security.access.Constants.RESOLVE);

        Caveat debugOnly = VSecurity.newCaveat(
                io.v.v23.security.access.Constants.ACCESS_TAG_CAVEAT, tags);
        Caveat expiration = VSecurity.newExpiryCaveat(DateTime.now().plus(duration));

        String privateKey;
        VPrincipal delegate;
        try {
            KeyPairGenerator e = KeyPairGenerator.getInstance("EC");
            e.initialize(256);
            KeyPair keyPair = e.generateKeyPair();
            privateKey = Base64.encodeToString(keyPair.getPrivate().getEncoded(), BASE64_FLAGS);
            delegate = VSecurity.newPrincipal(
                    VSecurity.newSigner(keyPair.getPrivate(), (ECPublicKey) keyPair.getPublic()));
        } catch (NoSuchAlgorithmException e) {
            throw new VException("Could not mint private key: " + e.getMessage());
        }
        VPrincipal me = V.getPrincipal(mCtx);
        Blessings b = me.bless(
                delegate.publicKey(),
                me.blessingStore().defaultBlessings(),
                "debugger" + io.v.v23.security.Constants.CHAIN_SEPARATOR + invitee,
                debugOnly,
                expiration);
        StringBuilder builder = new StringBuilder()
                .append("Please inspect my application using:")
                .append('\n')
                .append('\n')
                .append("debug browse")
                .append(" --key=").append(privateKey)
                .append(" --blessings=").append(Base64.encodeToString(
                        VomUtil.encode(b, b.getClass()), BASE64_FLAGS))
                .append(" ");
        if (mMountedName.length() > 0) {
            builder.append(mMountedName).append(" ");
        }
        for (Endpoint ep : V.getServer(mCtx).getStatus().getEndpoints()) {
            builder.append(ep.name()).append(" ");
        }
        return builder.toString();
    }

    private static String createMountedName(VContext ctx) throws NoSuchAlgorithmException {
        // TODO(ashankar): Use a conventions library here, something like
        // https://godoc.org/v.io/v23/conventions
        // What follows below is NOT worthy of any form of emulation!
        //
        // The intent is to create a unique name for this application that it will have
        // permission to mount under. The place it has permissions to mount under depends on
        // the kind of blessing: <idp>:u:<email>:... should have permissions under user/<email>/...
        // while <idp>:o:<appid>:<email> should ultimately go under apps/<appid>/users/<email>/...
        // but for now will be placed under tmp/debug/<something>.
        //
        // The hash of the public key of the principal is used to uniquely identify this particular
        // instance of the application.
        VPrincipal p = V.getPrincipal(ctx);
        String[] myNames = VSecurity.getBlessingNames(p, p.blessingStore().defaultBlessings());
        String uid = Base64.encodeToString(
                MessageDigest.getInstance("SHA-256").digest(p.publicKey().getEncoded()),
                BASE64_FLAGS);
        for (String n : myNames) {
            // Does this follow the "idp:u:<username>" path?
            String[] parts = n.split(io.v.v23.security.Constants.CHAIN_SEPARATOR);
            if (parts.length >=3 && parts[1].equals("u")) {
                return "users/" + parts[2] + "debug/" + uid;
            }
            if (parts.length >=4 && parts[1].equals("o")) {
                // TODO(ashankar,ribrdb): Replace this with whatever convention we end up with
                // when it comes to application blessings.
                return "tmp/debug/" + uid;
            }
        }
        return "";
    }
}
