/*
 * 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.knox.gateway;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.fail;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.directory.server.protocol.shared.transport.TcpTransport;
import org.apache.knox.gateway.config.GatewayConfig;
import org.apache.knox.gateway.security.ldap.SimpleLdapDirectoryServer;
import org.apache.knox.gateway.services.DefaultGatewayServices;
import org.apache.knox.gateway.services.ServiceLifecycleException;
import org.apache.knox.test.mock.MockServer;
import org.hamcrest.CoreMatchers;
import org.hamcrest.Matchers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.mycila.xmltool.XMLTag;

/**
 * This class was created to reduce much of the duplication and boiler plate that was ending up in the GatewayBasicFuncTest class.
 * It basically does a number of different things.
 * 1) Creates a GATEWAY_HOME starts a gateway instance and deployes a test topology.
 * 2) Provides a registry of mock Hadoop services.
 * 3) Provides "bundled" methods for common Hadoop operations to avoid duplication in tests.
 * 4) Provides methods to access test resources.
 */
public class GatewayTestDriver {
  private static final Logger log = LoggerFactory.getLogger( GatewayTestDriver.class );

  public Class<?> resourceBaseClass;
  public Map<String,Service> services = new HashMap<>();
  public SimpleLdapDirectoryServer ldap;
  public TcpTransport ldapTransport;
  public boolean useGateway;
  public GatewayServer gateway;
  public GatewayConfig config;
  public String clusterName;
  public DefaultGatewayServices srvcs;

  /**
   * Sets the class from which relative test resource names should be resolved.
   * @param resourceBaseClass The class from which relative test resource names should be resolved.
   */
  public void setResourceBase( Class<?> resourceBaseClass ) {
    this.resourceBaseClass = resourceBaseClass;
  }

  /**
   * Starts an embedded LDAP server of the specified port.
   * @param port The desired port the LDAP server should listen on.
   * @return The actual port the LDAP server is listening on.
   * @throws Exception Thrown if a failure occurs.
   */
  public int setupLdap( int port ) throws Exception {
    String basedir = System.getProperty("basedir");
    if (basedir == null) {
      basedir = new File(".").getCanonicalPath();
    }
    Path path = FileSystems.getDefault().getPath(basedir, "/src/test/resources/users.ldif");
    return setupLdap( port, path.toFile() );
  }

  public int setupLdap( int port, File ldifConfig ) throws Exception {
    ldapTransport = new TcpTransport( port );
    ldap = new SimpleLdapDirectoryServer( "dc=hadoop,dc=apache,dc=org", ldifConfig, ldapTransport );
    ldap.start();
    log.info( "LDAP port = " + ldapTransport.getAcceptor().getLocalAddress().getPort() );
    return port;
  }

  /**
   * Adds a mock service to the registry.
   * @param role role to create service for
   * @param realUrl real url for the service
   * @param gatewayPath gateway path to respond on
   * @param mock whether to mock or use real service from realUrl
   * @throws Exception Thrown if new service fails.
   */
  public void setupService( String role, String realUrl, String gatewayPath, boolean mock ) throws Exception {
    Service service = new Service( role, realUrl, gatewayPath, mock );
    services.put( role, service );
    log.info("{} port = {}", role, service.server.getPort());
  }

  /**
   * Creates a GATEWAY_HOME, starts a gateway instance and deploys a test topology.
   * @param config config for setting up the gateway
   * @param cluster cluster name to setup
   * @param topology topology to setup
   * @param use whether to use the gateway or real service
   * @throws Exception Thrown if failure during setup.
   */
  public void setupGateway( GatewayTestConfig config, String cluster, XMLTag topology, boolean use ) throws Exception {
    this.useGateway = use;
    this.config = config;
    this.clusterName = cluster;

    File targetDir = new File( System.getProperty( "user.dir" ), "target" );
    File gatewayDir = new File( targetDir, "gateway-home-" + UUID.randomUUID() );
    gatewayDir.mkdirs();

    config.setGatewayHomeDir( gatewayDir.getAbsolutePath() );

    File topoDir = new File( config.getGatewayTopologyDir() );
    topoDir.mkdirs();

    File descDir = new File( config.getGatewayDescriptorsDir() );
    descDir.mkdirs();

    File provConfDir = new File( config.getGatewayProvidersConfigDir() );
    provConfDir.mkdirs();

    File deployDir = new File( config.getGatewayDeploymentDir() );
    deployDir.mkdirs();

    File descriptor = new File( topoDir, cluster + ".xml" );
    try(OutputStream stream = Files.newOutputStream(descriptor.toPath())) {
        topology.toStream( stream );
    }

    this.srvcs = new DefaultGatewayServices();
    Map<String,String> options = new HashMap<>();
    options.put("persist-master", "false");
    options.put("master", "password");
    try {
      this.srvcs.init(config, options);
    } catch (ServiceLifecycleException e) {
      e.printStackTrace(); // I18N not required.
    }

    start();
  }

  public void start() throws Exception {
    gateway = GatewayServer.startGateway( config, srvcs );
    assertThat( "Failed to start gateway.", gateway, CoreMatchers.notNullValue() );
    log.info( "Gateway port = " + gateway.getAddresses()[ 0 ].getPort() );
  }

  public void stop() throws Exception {
    if (gateway != null) {
      gateway.stop();
    }
  }

  public void cleanup() throws Exception {
    stop();
    if ( config != null ) {
      FileUtils.deleteQuietly( new File( config.getGatewayTopologyDir() ) );
      FileUtils.deleteQuietly( new File( config.getGatewayConfDir() ) );
      FileUtils.deleteQuietly( new File( config.getGatewaySecurityDir() ) );
      FileUtils.deleteQuietly( new File( config.getGatewayDeploymentDir() ) );
      FileUtils.deleteQuietly( new File( config.getGatewayDataDir() ) );
    }

    for( Service service : services.values() ) {
      service.server.stop();
    }
    services.clear();

    if(ldap != null) {
      ldap.stop(true);
    }
  }

  public boolean isUseGateway() {
    return useGateway;
  }

  public MockServer getMock( String serviceRole ) {
    Service service = services.get( serviceRole );
    return service.server;
  }

  public String getRealUrl( String serviceRole ) {
    return getUrl( serviceRole, true );
  }

  public String getUrl( String serviceRole ) {
    return getUrl( serviceRole, false );
  }

  private String getLocalHostName() {
    String hostName = "localhost";
    try {
      hostName = InetAddress.getByName( "127.0.0.1" ).getHostName();
    } catch( UnknownHostException e ) {
      // Ignore and use the default.
    }
    return hostName;
  }

  public String getUrl( String serviceRole, boolean real ) {
    String url;
    String localHostName = getLocalHostName();
    Service service = services.get( serviceRole );
    if( useGateway && !real ) {
      url = "http://" + localHostName + ":" + gateway.getAddresses()[0].getPort() + "/" + config.getGatewayPath() + service.gatewayPath;
    } else if( service.mock ) {
      url = "http://" + localHostName + ":" + service.server.getPort();
    } else {
      url = service.realUrl.toASCIIString();
    }
    return url;
  }

  public String getClusterUrl() {
    String url;
    String localHostName = getLocalHostName();
    url = "http://" + localHostName + ":" + gateway.getAddresses()[0].getPort() + "/" + config.getGatewayPath() + "/" + clusterName;
    return url;
  }

  public int getGatewayPort() {
    return gateway.getAddresses()[0].getPort();
  }

  public String getRealAddr( String role ) {
    String addr;
    String localHostName = getLocalHostName();
    Service service = services.get( role );
    if( service.mock ) {
      addr = localHostName + ":" + service.server.getPort();
    } else {
      addr = service.realUrl.getHost() + ":" + service.realUrl.getPort();
    }
    return addr;
  }

  public String getLdapUrl() {
    return "ldap://localhost:" + ldapTransport.getAcceptor().getLocalAddress().getPort();
  }

  private static class Service {
    String role;
    URI realUrl;
    String gatewayPath;
    boolean mock;
    MockServer server;
    Service( String role, String realUrl, String gatewayPath, boolean mock ) throws Exception {
      this.role = role;
      this.realUrl = new URI( realUrl );
      this.gatewayPath = gatewayPath;
      this.mock = mock;
      this.server = new MockServer( role, true );
    }
  }

  public String getResourceBaseName() {
    return resourceBaseClass.getName().replaceAll( "\\.", "/" ) + "/";
  }

  public String getResourceName( String resource ) {
    return getResourceBaseName() + resource;
  }

  public URL getResourceUrl( String resource ) {
    URL url = ClassLoader.getSystemResource( getResourceName( resource ) );
    assertThat( "Failed to find test resource " + resource, url, Matchers.notNullValue() );
    return url;
  }

  public InputStream getResourceStream( String resource ) throws IOException {
    InputStream stream;
    if( resource.startsWith( "file:/" ) ) {
      try {
        stream = FileUtils.openInputStream( new File( new URI( resource ) ) );
      } catch( URISyntaxException e ) {
        throw new IOException( e  );
      }
    } else {
      stream = ClassLoader.getSystemResourceAsStream( getResourceName( resource ) );
    }
    assertThat( "Failed to find test resource " + resource, stream, Matchers.notNullValue() );
    return stream;
  }

  public byte[] getResourceBytes( String resource ) throws IOException {
    return IOUtils.toByteArray( getResourceStream( resource ) );
  }

  public String getResourceString( String resource ) throws IOException {
    return IOUtils.toString( getResourceBytes( resource ), StandardCharsets.UTF_8.name() );
  }

  public void assertComplete() {
    // Check to make sure that all interaction were satisfied if for mocked services.
    // Otherwise just clear the mock interaction queue.
    for( Service service : services.values() ) {
      if( service.mock ) {
        assertThat(
            "Service " + service.role + " has remaining expected interactions.",
            service.server.getCount(), Matchers.is(0) );
      }
      service.server.reset();
    }
  }


  public void assertNotComplete(String serviceName) {
    // Check to make sure that all interaction were satisfied if for mocked services.
    // Otherwise just clear the mock interaction queue.

    Service service = services.get(serviceName);

    if(service != null) {
      if(service.mock) {
        assertThat(
            "Service " + service.role + " has remaining expected interactions.",
            service.server.getCount(), Matchers.not(0));
      }
      service.server.reset();
    } else {
      fail();
    }
  }

  public void reset() {
    for( Service service : services.values() ) {
      service.server.reset();
    }
  }
}
