// 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.access;

import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;

import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;

import io.v.v23.V;
import io.v.v23.context.VContext;
import io.v.v23.security.BlessingPattern;
import io.v.v23.security.BlessingRoots;
import io.v.v23.security.Blessings;
import io.v.v23.security.Call;
import io.v.v23.security.CallParams;
import io.v.v23.security.Constants;
import io.v.v23.security.VPrincipal;
import io.v.v23.security.VSecurity;
import io.v.v23.security.VSigner;
import io.v.v23.security.access.internal.MyObjectServerWrapper;
import io.v.v23.security.access.internal.MyTag;
import io.v.v23.vdl.VdlValue;
import io.v.v23.verror.VException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import java.security.interfaces.ECPublicKey;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import static org.junit.Assert.fail;


/**
 * Tests the implementation of {@code PermissionsAuthorizer}.
 */
@RunWith(Parameterized.class)
public class PermissionsAuthorizerTest {
    private static final VContext CONTEXT;
    private static final PermissionsAuthorizer AUTHORIZER;
    private static final VPrincipal CLIENT_PRINCIPAL;
    private static final VPrincipal SERVER_PRINCIPAL;
    private static final Blessings SERVER_BLESSINGS;

    static {
        CONTEXT = V.init();
        Permissions perms = new Permissions(ImmutableMap.of(
                "R", new AccessList(
                        ImmutableList.of(Constants.ALL_PRINCIPALS),
                        null),
                "W", new AccessList(
                        ImmutableList.of(
                                new BlessingPattern("ali/family"),
                                new BlessingPattern("bob"),
                                new BlessingPattern("che/$")),
                        ImmutableList.of(
                                "bob/acquaintances")),
                "X", new AccessList(
                        ImmutableList.of(
                                new BlessingPattern("ali/family/boss/$"),
                                new BlessingPattern("superman/$")),
                        null)
        ));
        try {
            AUTHORIZER = PermissionsAuthorizer.create(perms, MyTag.class);
            CLIENT_PRINCIPAL = newPrincipal();
            SERVER_PRINCIPAL = newPrincipal();
            SERVER_BLESSINGS = SERVER_PRINCIPAL.blessSelf("server");
        } catch (VException e) {
            throw new RuntimeException(e);
        }
    }

    private static VPrincipal newPrincipal() throws VException {
        VSigner signer = VSecurity.newInMemorySigner();
        return VSecurity.newPrincipal(signer, null, new TrustAllRoots());
    }

    private static VdlValue[] getMethodTags(String method) throws VException {
        MyObjectServerWrapper s = new MyObjectServerWrapper(null);
        return s.getMethodTags(method);
    }

    private final String methodName;
    private final Blessings clientBlessings;
    private final boolean shouldAccept;
    private final VdlValue[] methodTags;

    @Parameterized.Parameters
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[][]{
                {"get", ImmutableList.of(), true},
                {"get", ImmutableList.of("ali"), true},
                {"get", ImmutableList.of("bob/friend", "che/enemy"), true},
                {"put", ImmutableList.of("ali/family/mom"), true},
                {"put", ImmutableList.of("bob/friends"), true},
                // granted because of "che"
                {"put", ImmutableList.of("bob/acquantainces/carol", "che"), true},
                {"resolve", ImmutableList.of("superman"), true},
                {"resolve", ImmutableList.of("ali/family/boss"), true},

                {"put", ImmutableList.of("ali", "bob/acquaintances", "bob/acquaintances/dave",
                        "che/friend", "dave"), false},
                {"resolve", ImmutableList.of("ali", "ali/friend", "ali/family", "ali/family/friend",
                        "alice/family/boss/friend", "superman/friend"), false},
                // Since there are no tags on the noTags method, it has an
                // empty ACL.  No client will have access.
                {"noTags", ImmutableList.of(
                        "ali", "ali/family/boss", "bob", "che", "superman"), false}
        });
    }

    public PermissionsAuthorizerTest(String methodName, List<String> clientBlessingNames,
                                     boolean isAccepted) throws VException {
        this.methodName = methodName;
        this.methodTags = new MyObjectServerWrapper(null).getMethodTags(methodName);
        this.clientBlessings = VSecurity.unionOfBlessings(Lists.transform(
                clientBlessingNames, new Function<String, Blessings>() {
                    @Override
                    public Blessings apply(String name) {
                        try {
                            return CLIENT_PRINCIPAL.blessSelf(name);
                        } catch (VException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }).toArray(new Blessings[0]));
        this.shouldAccept = isAccepted;
    }

    @Test
    public void testAuthorize() {
        Call call = VSecurity.newCall(new CallParams()
                .withLocalPrincipal(SERVER_PRINCIPAL)
                .withLocalBlessings(SERVER_BLESSINGS)
                .withRemoteBlessings(clientBlessings)
                .withMethod(methodName)
                .withMethodTags(methodTags));
        try {
            AUTHORIZER.authorize(CONTEXT, call);
            if (!shouldAccept) {
                fail(String.format(
                        "Access granted for method %s to %s", methodName, clientBlessings));
            }
        } catch (VException e) {
            if (shouldAccept) {
                fail(String.format(
                        "Access denied for method %s to %s", methodName, clientBlessings));
            }
        }
    }

    private static class TrustAllRoots implements BlessingRoots {
        @Override
        public void add(ECPublicKey root, BlessingPattern pattern) throws VException {}
        @Override
        public void recognized(ECPublicKey root, String blessing) throws VException {}
        @Override
        public String debugString() { return TrustAllRoots.class.toString(); }
        @Override
        public Multimap<BlessingPattern, ECPublicKey> dump() {
            return ImmutableMultimap.of();
        }
    }
}