/*
 * Copyright 2017 The Mifos Initiative.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.mifos.anubis.security;

import io.mifos.anubis.api.v1.domain.AllowedOperation;
import io.mifos.core.api.util.ApiConstants;
import io.mifos.core.lang.ApplicationName;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.mockito.Mockito;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Collection;

import static org.mockito.Mockito.when;

/**
 * @author Myrle Krantz
 */
@RunWith(Parameterized.class)
public class ApplicationPermissionTest {

  private static class TestCase
  {
    private final String caseName;
    private String permittedPath = "/heart";
    private AllowedOperation allowedOperation = AllowedOperation.READ;
    private boolean acceptTokenIntendedForForeignApplication = false;
    private String calledApplication = "graincounter-v1";
    private String requestedPath = "/heart";
    private String requestedOperation = "GET";
    private String user = "Nebamun";
    private String forApplication = "graincounter-v1";
    private boolean expectedResult = true;

    private TestCase(final String caseName) {
      this.caseName = caseName;
    }

    String getPermittedPath() {
      return permittedPath;
    }

    TestCase permittedPath(String permittedPath) {
      this.permittedPath = permittedPath;
      return this;
    }

    AllowedOperation getAllowedOperation() {
      return allowedOperation;
    }

    TestCase allowedOperation(AllowedOperation allowedOperation) {
      this.allowedOperation = allowedOperation;
      return this;
    }

    boolean isAcceptTokenIntendedForForeignApplication() {
      return acceptTokenIntendedForForeignApplication;
    }

    TestCase acceptTokenIntendedForForeignApplication(boolean newVal) {
      this.acceptTokenIntendedForForeignApplication = newVal;
      return this;
    }

    ApplicationName getCalledApplication() {
      return ApplicationName.fromSpringApplicationName(calledApplication);
    }

    TestCase calledApplication(final String newVal)
    {
      this.calledApplication = newVal;
      return this;
    }


    String getRequestedPath() {
      return requestedPath;
    }

    TestCase requestedPath(String requestedPath) {
      this.requestedPath = requestedPath;
      return this;
    }

    String getRequestedOperation() {
      return requestedOperation;
    }

    TestCase requestedOperation(String requestedOperation) {
      this.requestedOperation = requestedOperation;
      return this;
    }

    AnubisPrincipal getPrincipal() {
      return new AnubisPrincipal(user, forApplication);
    }

    TestCase user(final String newVal)
    {
      this.user = newVal;
      return this;
    }

    TestCase forApplication(final String newVal)
    {
      this.forApplication = newVal;
      return this;
    }

    boolean getExpectedResult() {
      return expectedResult;
    }

    TestCase expectedResult(boolean expectedResult) {
      this.expectedResult = expectedResult;
      return this;
    }

    @Override public String toString() {
      return caseName;
    }
  }

  private final TestCase testCase;

  public ApplicationPermissionTest(final TestCase testCase) {
    this.testCase = testCase;
  }

  @Parameterized.Parameters
  public static Collection testCases() {
    final Collection<TestCase> ret = new ArrayList<>();

    ret.add(new TestCase("Happy case"));
    ret.add(new TestCase("Different operation").requestedOperation("DELETE").expectedResult(false));
    ret.add(new TestCase("Delete operation").allowedOperation(AllowedOperation.DELETE).requestedOperation("DELETE").expectedResult(true));
    ret.add(new TestCase("Different path requested").requestedPath("/soul").expectedResult(false));
    ret.add(new TestCase("* in request").requestedPath("/heart/*").expectedResult(false));
    ret.add(new TestCase("* in permission pattern matching").permittedPath("/heart/*").expectedResult(true));
    ret.add(new TestCase("safe").permittedPath("/w-x+y.z/").requestedPath("/w-x+y.z/").expectedResult(true));
    ret.add(new TestCase("escape").permittedPath("/%f005/").requestedPath("/%f005/").expectedResult(true));
    ret.add(new TestCase("digit")
        .permittedPath("/555/555").requestedPath("/555/555")
        .expectedResult(true));
    ret.add(new TestCase("multiple end segments matched to *")
        .permittedPath("/heart/*").requestedPath("/heart/soul/body")
        .expectedResult(true));
    ret.add(new TestCase("* in the middle")
        .permittedPath("/*/heart").requestedPath("/soul/heart")
        .expectedResult(true));
    ret.add(new TestCase("{useridentifier} in the middle")
        .permittedPath("/{useridentifier}/ka").requestedPath("/Nebamun/ka")
        .expectedResult(true));
    ret.add(new TestCase("wrong {useridentifier} in request")
        .permittedPath("/{useridentifier}/ka").requestedPath("/Menna/ka")
        .expectedResult(false));
    ret.add(new TestCase("{useridentifier} and *")
        .permittedPath("/{useridentifier}/*").requestedPath("/Nebamun/ka/arua")
        .expectedResult(true));
    ret.add(new TestCase("{parameter} with su").user(ApiConstants.SYSTEM_SU)
        .permittedPath("/{parameter}/").requestedPath("/value")
        .expectedResult(true));
    ret.add(new TestCase("{parameter} without su")
         .permittedPath("/{parameter}/").requestedPath("/value")
         .expectedResult(false));
    ret.add(new TestCase("* at end with request containing more segments")
         .permittedPath("/roles/*").requestedPath("/users/antony/password")
         .expectedResult(false));
    ret.add(new TestCase("* at end with request containing same # segments")
            .permittedPath("/x/y/z/*").requestedPath("/m/n/o/")
            .expectedResult(false));
    ret.add(new TestCase("{applicationidentifier} but permission doesn't allow foreign forApplication")
            .permittedPath("/m/{applicationidentifier}/o").requestedPath("/m/bcde-v1/o/")
            .acceptTokenIntendedForForeignApplication(false)
            .calledApplication("abcd-v1").forApplication("bcde-v1")
            .expectedResult(false));
    ret.add(new TestCase("{applicationidentifier} and permission does allow foreign forApplication")
            .permittedPath("/m/{applicationidentifier}/o").requestedPath("/m/bcde-v1/o/")
            .acceptTokenIntendedForForeignApplication(true)
            .calledApplication("abcd-v1").forApplication("bcde-v1")
            .expectedResult(true));
    ret.add(new TestCase("No {applicationidentifier} even though permission does allow foreign forApplication")
            .permittedPath("/m/n/o").requestedPath("/m/bcde-v1/o/")
            .acceptTokenIntendedForForeignApplication(true)
            .calledApplication("abcd-v1").forApplication("bcde-v1")
            .expectedResult(false));
    ret.add(new TestCase("{applicationidentifier} and permission does allow foreign forApplication, but application isn't foreign.")
            .permittedPath("/m/{applicationidentifier}/o").requestedPath("/m/abcd-v1/o/")
            .acceptTokenIntendedForForeignApplication(true)
            .calledApplication("abcd-v1").forApplication("abcd-v1")
            .expectedResult(true));
    ret.add(new TestCase("initialize")
            .permittedPath("/initialize").requestedPath("/initialize")
            .acceptTokenIntendedForForeignApplication(false)
            .calledApplication("abcd-v1").forApplication("abcd-v1")
            .allowedOperation(AllowedOperation.CHANGE)
            .requestedOperation("POST")
            .expectedResult(true));

    return ret;
  }

  @Test public void test() {
    final ApplicationPermission testSubject =
        new ApplicationPermission(testCase.getPermittedPath(), testCase.getAllowedOperation(), testCase.isAcceptTokenIntendedForForeignApplication());

    final HttpServletRequest requestMock = Mockito.mock(HttpServletRequest.class);
    when(requestMock.getServletPath()).thenReturn(testCase.getRequestedPath());
    when(requestMock.getMethod()).thenReturn(testCase.getRequestedOperation());

    final boolean matches = testSubject.matches(requestMock, testCase.getCalledApplication(), testCase.getPrincipal());

    Assert.assertEquals("Testcase gave wrong result: '" + testCase.toString() + "'",
        testCase.getExpectedResult(), matches);
    Assert.assertEquals("Testcase contains wrong allowed operation: '" + testCase.toString() + "'",
        testCase.getAllowedOperation(), testSubject.getAllowedOperation());
    Assert.assertEquals("Testcase contains wrong authority: '" + testCase.toString() + "'",
        "maats_feather", testSubject.getAuthority());
  }
}
