/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The ASF licenses this file to You 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 org.apache.geode.management.internal.security;

import static org.apache.geode.test.awaitility.GeodeAwaitility.await;

import java.util.List;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;

import org.apache.geode.examples.SimpleSecurityManager;
import org.apache.geode.internal.logging.LogService;
import org.apache.geode.test.dunit.AsyncInvocation;
import org.apache.geode.test.dunit.IgnoredException;
import org.apache.geode.test.dunit.VM;
import org.apache.geode.test.dunit.rules.ClusterStartupRule;
import org.apache.geode.test.junit.categories.SecurityTest;
import org.apache.geode.test.junit.rules.GfshCommandRule;
import org.apache.geode.test.junit.rules.GfshCommandRule.PortType;
import org.apache.geode.test.junit.rules.Member;

@Category({SecurityTest.class})
public class MultiGfshDUnitTest {

  @Rule
  public ClusterStartupRule lsRule = new ClusterStartupRule();

  private Member server;

  @Before
  public void setup() throws Exception {
    server = lsRule.startServerVM(0,
        x -> x.withJMXManager().withSecurityManager(SimpleSecurityManager.class));
  }

  @Test
  public void testMultiUser() throws Exception {
    IgnoredException.addIgnoredException("java.util.zip.ZipException: zip file is empty");
    IgnoredException
        .addIgnoredException("java.lang.IllegalStateException: WAN service is not available.");
    int jmxPort = server.getJmxPort();

    // set up vm_1 as a gfsh vm, data-reader will login and log out constantly in this vm until the
    // test is done.
    VM vm1 = lsRule.getVM(1);
    vm1.invokeAsync("run as data-reader", () -> {
      while (true) {
        GfshCommandRule gfsh = new GfshCommandRule(server::getJmxPort, PortType.jmxManager);
        gfsh.secureConnectAndVerify(jmxPort, PortType.jmxManager, "dataRead", "dataRead");

        await();
        gfsh.close();
      }
    });

    VM vm2 = lsRule.getVM(2);
    // set up vm_2 as a gfsh vm, and then connect as "stranger" and try to execute the commands and
    // assert errors comes back are NotAuthorized
    AsyncInvocation vm2Invoke = vm2.invokeAsync("run as guest", () -> {
      GfshCommandRule gfsh = new GfshCommandRule();
      gfsh.secureConnectAndVerify(jmxPort, PortType.jmxManager, "guest", "guest");

      List<TestCommand> allCommands = TestCommand.getOnlineCommands();
      for (TestCommand command : allCommands) {
        LogService.getLogger().info("executing: " + command.getCommand());
        gfsh.executeAndAssertThat(command.getCommand()).statusIsError()
            .containsOutput("Unauthorized");
      }

      gfsh.close();
      LogService.getLogger().info("vm 2 done!");
    });


    VM vm3 = lsRule.getVM(3);
    IgnoredException
        .addIgnoredException("java.lang.IllegalArgumentException: Region does not exist: {0}", vm3);
    IgnoredException.addIgnoredException("java.lang.ClassNotFoundException: myApp.myListener", vm3);

    // set up vm_3 as another gfsh vm, and then connect as "super-user" and try to execute the
    // commands and assert we don't get a NotAuthorized Exception
    AsyncInvocation vm3Invoke = vm3.invokeAsync("run as superUser", () -> {
      GfshCommandRule gfsh = new GfshCommandRule();
      gfsh.secureConnectAndVerify(jmxPort, PortType.jmxManager, "data,cluster", "data,cluster");

      List<TestCommand> allCommands = TestCommand.getOnlineCommands();
      for (TestCommand command : allCommands) {
        LogService.getLogger().info("executing: " + command.getCommand());
        gfsh.executeAndAssertThat(command.getCommand()).doesNotContainOutput("Unauthorized");
      }
      gfsh.close();
      LogService.getLogger().info("vm 3 done!");
    });

    // only wait until vm2 and vm3 are done. vm1 will close when test finishes
    vm2Invoke.join();
    vm3Invoke.join();

    vm2Invoke.checkException();
    vm3Invoke.checkException();

    IgnoredException.removeAllExpectedExceptions();
  }

}
