/*
 * 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.slider.funtest.tomcat

import groovy.util.logging.Slf4j
import org.apache.hadoop.conf.Configuration
import org.apache.hadoop.fs.FileSystem
import org.apache.hadoop.fs.FileUtil
import org.apache.hadoop.fs.FileStatus
import org.apache.hadoop.fs.Path
import org.apache.hadoop.registry.client.types.ServiceRecord
import org.apache.slider.api.ClusterDescription
import org.apache.slider.client.SliderClient
import org.apache.slider.common.SliderKeys
import org.apache.slider.core.conf.ConfTree
import org.apache.slider.core.persist.ConfTreeSerDeser
import org.apache.slider.core.registry.docstore.PublishedConfiguration
import org.apache.slider.core.registry.retrieve.RegistryRetriever
import org.apache.slider.funtest.framework.SliderShell
import org.apache.slider.providers.agent.AgentKeys

import org.junit.Before
import org.junit.Test

import static org.apache.hadoop.registry.client.binding.RegistryUtils.currentUser
import static org.apache.hadoop.registry.client.binding.RegistryUtils.servicePath

@Slf4j
class TomcatBasicIT extends TomcatAgentCommandTestBase {
  protected ConfTree tree

  protected String getAppResource() {
    return sysprop("test.app.resources.dir") + "/resources.json"
  }

  protected String templateName() {
    return sysprop("test.app.resources.dir") + "/appConfig.json"
  }

  protected String getDefaultTemplate() {
    return sysprop("test.app.resources.dir") + "/appConfig-default.json"
  }

  protected String getAppTemplate() {
    String appTemplateFile = templateName()
    Configuration conf = new Configuration()
    FileSystem fs = FileSystem.getLocal(conf)
    InputStream stream = new FileInputStream(getDefaultTemplate())
    assert stream!=null, "Couldn't pull appConfig.json from app pkg"
    ConfTreeSerDeser c = new ConfTreeSerDeser()
    ConfTree t = c.fromStream(stream)
    t = modifyTemplate(t)
    log.info("Writing new template to {}", appTemplateFile)
    c.save(fs, new Path(appTemplateFile), t, true)
    return appTemplateFile
  }

  protected ConfTree modifyTemplate(ConfTree original) {
    // Set our custom WAR file in the appConfig and load it to the "cluster" filesystem
    Configuration conf = new Configuration()
    FileSystem fs = FileSystem.getLocal(conf)
    // The path from the local filesystem of the war (copied to target/test-classes from src/test/resources)
    Path sourcePath = fs.makeQualified(new Path(sysprop("test-classes.dir") + "/slider-test.war"))
    // Path in HDFS we'll put the WAR
    Path targetPath = clusterFS.makeQualified(new Path("/tmp/slider-test.war"))
    if (clusterFS.exists(targetPath)) {
      log.info("Deleting {}", targetPath)
      clusterFS.delete(targetPath, true)
    }
    log.info("Copying {} on {} to {} on {}", sourcePath, fs, targetPath, clusterFS)
    // Copy the file
    FileUtil.copy(fs, sourcePath, clusterFS, targetPath, false, true, clusterFS.getConf())
    FileStatus fileStatus = clusterFS.getFileStatus(targetPath)
    FileStatus origFileStatus = fs.getFileStatus(sourcePath)
    assert origFileStatus.getLen() == fileStatus.getLen(), "Expected file length to be the same in both source and destination"

    log.info("Setting {} to {} in appConfig.json", AgentKeys.APP_RESOURCES, targetPath.toString())
    // Set that path in the appConfig
    original.global.put(AgentKeys.APP_RESOURCES, targetPath.toString())

    return original
  }

  @Override
  public String getClusterName() {
    return "test_tomcat_basic"
  }

  protected Map<String, Integer> getRoleMap() {
    // must match the values in src/test/resources/resources.json
    return [
      "TOMCAT" : 1
    ];
  }

  @Test
  public void testTomcatClusterCreate() throws Throwable {

    describe getDescription()

    def path = buildClusterPath(getClusterName())
    assert !clusterFS.exists(path)

    SliderShell shell = createTemplatedSliderApplication(getClusterName(),
      APP_TEMPLATE, APP_RESOURCE, [])

    logShell(shell)

    ensureApplicationIsUp(getClusterName())

    //get a slider client against the cluster
    SliderClient sliderClient = bondToCluster(SLIDER_CONFIG, getClusterName())
    ClusterDescription cd = sliderClient.clusterDescription
    assert getClusterName() == cd.name

    log.info("Connected via Client {}", sliderClient.toString())

    //wait for the role counts to be reached, containers to get launched
    waitForRoleCount(sliderClient, getRoleMap(), TOMCAT_LAUNCH_WAIT_TIME)

    // Wait for Tomcat itself to boot
    sleep(TOMCAT_LAUNCH_WAIT_TIME);

    clusterLoadOperations(cd, sliderClient)
  }


  public String getDescription() {
    return "Create a working Tomcat cluster $clusterName"
  }

  public static PublishedConfiguration getExport(SliderClient sliderClient,
                                                 String clusterName,
                                                 String exportName) {
    String path = servicePath(currentUser(),
      SliderKeys.APP_TYPE,
      clusterName);
    ServiceRecord instance = sliderClient.resolve(path)
    RegistryRetriever retriever = new RegistryRetriever(
        sliderClient.config,
        instance)
    PublishedConfiguration configuration = retriever.retrieveConfiguration(
      retriever.getConfigurations(true), exportName, true)
    return configuration
  }

  /**
   * Override point for any cluster load operations
   */
  public void clusterLoadOperations(ClusterDescription cd, SliderClient sliderClient) {
    String httpAddress = getHttpAddress(sliderClient, getClusterName())
    assert httpAddress.startsWith("http://"), "Tomcat HTTP URL didn't have expected protocol"
    checkHttpAddress(httpAddress)
  }

  /**
   * Attempt to fetch the published Tomcat webserver address from the quicklinks.
   */
  public static String getHttpAddress(SliderClient sliderClient, String clusterName) {
    int tries = 5
    Exception caught;
    while (true) {
      try {
        PublishedConfiguration configuration = getExport(sliderClient,
          clusterName, "quicklinks")

        // must match name set in metainfo.xml
        String httpAddress = configuration.entries.get("HTTP")
        assertNotNull httpAddress
        log.info("Got exported server address: '{}'", httpAddress)
        return httpAddress
      } catch (Exception e) {
        caught = e;
        log.info("Got exception trying to read quicklinks")
        if (tries-- == 0) {
          break
        }
        sleep(20000)
      }
    }
    throw caught;
  }

  /**
   * Validate the URL for the Tomcat server, checking deployed web content.
   */
  public static void checkHttpAddress(String serverAddress) {
    // Check the Tomcat manager webapp
    String page = fetchWebPageRaisedErrorCodes(serverAddress);
    assert page != null, "Tomcat manager page null"
    assert page.length() > 100, "Tomcat manager page too short"
    assert page.contains("Apache Tomcat"), "Tomcat monitor page didn't contain expected text"

    // Check our test war we deployed too
    page = fetchWebPageRaisedErrorCodes(serverAddress + '/slider-test');
    assert page != null, "Could not fetch auto-deployed webapp"
    // The custom war file will return a plain-text response of "Success" for "/"
    assert page == "Success", "Did not find the expected content produced by the webapp"
  }
}
