/*
 * 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.agent.rest

import groovy.transform.CompileStatic
import groovy.util.logging.Slf4j
import org.apache.hadoop.registry.client.api.RegistryOperations
import org.apache.hadoop.yarn.api.records.ApplicationReport
import org.apache.slider.agent.AgentMiniClusterTestBase
import org.apache.slider.client.SliderClient
import org.apache.slider.client.ipc.SliderApplicationIpcClient
import org.apache.slider.client.rest.RestClientFactory
import org.apache.slider.common.SliderKeys
import org.apache.slider.common.SliderXmlConfKeys
import org.apache.slider.common.params.Arguments
import org.apache.slider.core.main.ServiceLauncher
import org.apache.slider.core.restclient.HttpOperationResponse
import org.apache.slider.server.appmaster.rpc.RpcBinder
import org.junit.Test

import static org.apache.slider.server.appmaster.management.MetricsKeys.*
import static org.apache.slider.server.appmaster.web.rest.RestPaths.*

@CompileStatic
@Slf4j
class TestStandaloneREST extends AgentMiniClusterTestBase {


  @Test
  public void testStandaloneREST() throws Throwable {

    describe "create a standalone AM then perform actions on it"
    //launch fake master
    def conf = configuration
    conf.setBoolean(METRICS_LOGGING_ENABLED, true)
    conf.setInt(METRICS_LOGGING_LOG_INTERVAL, 1)
    String clustername = createMiniCluster("", conf, 1, true)


    ServiceLauncher<SliderClient> launcher =
        createStandaloneAMWithArgs(clustername,
            [Arguments.ARG_OPTION,
             AbstractRestTestDelegate.TEST_GLOBAL_OPTION, 
             AbstractRestTestDelegate.TEST_GLOBAL_OPTION_PRESENT],
            true, false)
    SliderClient client = launcher.service
    addToTeardown(client);

    ApplicationReport report = waitForClusterLive(client)
    def proxyAM = report.trackingUrl
    def directAM = report.originalTrackingUrl
    
    
    // set up url config to match
    initHttpTestSupport(launcher.configuration)

    execOperation(WEB_STARTUP_TIME) {
      GET(directAM)
    }
    
    execOperation(WEB_STARTUP_TIME) {
      def metrics = GET(directAM, SYSTEM_METRICS_JSON)
      log.info prettyPrintJson(metrics)
    }

    GET(proxyAM)

    log.info GET(proxyAM, SYSTEM_PING)
    log.info GET(proxyAM, SYSTEM_THREADS)
    log.info GET(proxyAM, SYSTEM_HEALTHCHECK)
    log.info GET(proxyAM, SYSTEM_METRICS_JSON)

    // using the metrics, await the first node status update
    /* SLIDER--82: disabled
    awaitGaugeValue(
        appendToURL(proxyAM, SYSTEM_METRICS_JSON),
        "org.apache.slider.server.appmaster.state.RoleHistory.nodes-updated.flag",
        1,
        WEB_STARTUP_TIME  * 2, 500)
     */

    // Is the back door required? If so, don't test complex verbs via the proxy
    def proxyComplexVerbs = !SliderXmlConfKeys.X_DEV_INSECURE_REQUIRED

    //  Only do direct complex verbs if the no back door is needed, or if
    //  it is enabled
    def directComplexVerbs = proxyComplexVerbs || SLIDER_CONFIG.getBoolean(
        SliderXmlConfKeys.X_DEV_INSECURE_WS,
        SliderXmlConfKeys.X_DEV_INSECURE_DEFAULT)

    describe "Direct response headers from AM Web resources"
    def liveResUrl = appendToURL(directAM, SLIDER_PATH_APPLICATION, LIVE_RESOURCES);
    HttpOperationResponse response = executeGet(liveResUrl)
    response.headers.each { key, val -> log.info("$key $val") }
    log.info "Content type: ${response.contentType}"

    describe "proxied response headers from AM Web resources"
    response = executeGet(appendToURL(proxyAM, SLIDER_PATH_APPLICATION, LIVE_RESOURCES))
    response.headers.each { key, val -> log.info("$key $val") }
    log.info "Content type: ${response.contentType}"

    def ugiClient = createUGIJerseyClient();

    describe "Proxy SliderRestClient Tests"
    RestAPIClientTestDelegates proxySliderRestAPI =
        new RestAPIClientTestDelegates(proxyAM, ugiClient, proxyComplexVerbs)
    proxySliderRestAPI.testSuiteGetOperations()

    describe "Direct SliderRestClient Tests"
    RestAPIClientTestDelegates directSliderRestAPI =
        new RestAPIClientTestDelegates(directAM, ugiClient, directComplexVerbs)
    directSliderRestAPI.testSuiteAll()

    describe "Proxy Jersey Tests"
    JerseyTestDelegates proxyJerseyTests =
        new JerseyTestDelegates(proxyAM, ugiClient, proxyComplexVerbs)
    proxyJerseyTests.testSuiteGetOperations()

    describe "Direct Jersey Tests"

    JerseyTestDelegates directJerseyTests = new JerseyTestDelegates(directAM, ugiClient)
    directJerseyTests.testSuiteAll()

    describe "Direct Tests"

    LowLevelRestTestDelegates direct = new LowLevelRestTestDelegates(directAM, directComplexVerbs)
    direct.testSuiteAll()

    describe "Proxy Tests"

    LowLevelRestTestDelegates proxied = new LowLevelRestTestDelegates(proxyAM, proxyComplexVerbs)
    proxied.testSuiteAll()

    // create the Rest client via the registry

    RegistryOperations operations = client.registryOperations;
    def restClientFactory = new RestClientFactory(
        operations,
        ugiClient,
        "~", SliderKeys.APP_TYPE,
        clustername)
    def sliderApplicationApi = restClientFactory.createSliderAppApiClient();
    sliderApplicationApi.desiredModel
    sliderApplicationApi.resolvedModel

    if (directComplexVerbs) {
      sliderApplicationApi.ping("registry located")
    }

    describe( "IPC equivalent operations")
    def sliderClusterProtocol = RpcBinder.getProxy(conf, report, 1000)
    SliderApplicationIpcClient ipcClient = new SliderApplicationIpcClient(sliderClusterProtocol)
    IpcApiClientTestDelegates ipcDelegates = new IpcApiClientTestDelegates(ipcClient)
    ipcDelegates.testSuiteAll()

    // log the metrics to show what's up
    direct.logCodahaleMetrics();

    // finally, stop the AM
    if (directComplexVerbs) {
      describe "Stopping AM via REST API"
      directSliderRestAPI.testStop();
    }
  }

}
