/*
 * 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.server.appmaster.web.rest.agent;

import com.google.common.base.Preconditions;
import com.sun.jersey.api.core.ResourceConfig;
import com.sun.jersey.spi.container.WebApplication;
import com.sun.jersey.spi.container.servlet.ServletContainer;
import com.sun.jersey.spi.container.servlet.WebConfig;
import com.sun.jersey.spi.inject.SingletonTypeInjectableProvider;
import org.apache.slider.core.conf.MapOperations;
import org.apache.slider.server.appmaster.web.WebAppApi;
import org.apache.slider.server.appmaster.web.rest.RestPaths;
import org.apache.slider.server.services.security.SecurityUtils;
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.security.SslSelectChannelConnector;
import org.mortbay.jetty.servlet.Context;
import org.mortbay.jetty.servlet.ServletHolder;
import org.mortbay.thread.QueuedThreadPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.ws.rs.ext.Provider;
import java.io.File;
import java.util.Set;

/**
 *
 */
public class AgentWebApp {
  protected static final Logger LOG = LoggerFactory.getLogger(AgentWebApp.class);
  private int port;
  private int securedPort;
  private static Server agentServer;
  public static final String BASE_PATH = "slideragent";

  public static class Builder {
    final String name;
    final String wsName;
    final WebAppApi application;
    MapOperations configsMap;

    public Builder(String name, String wsName, WebAppApi application) {
      this.name = name;
      this.wsName = wsName;
      this.application = application;
    }

    public Builder withComponentConfig(MapOperations appMasterConfig) {
      this.configsMap = appMasterConfig;
      return this;
    }

    public AgentWebApp start() {
      if (configsMap == null) {
        throw new IllegalStateException("No SSL Configuration Available");
      }

      agentServer = new Server();
      agentServer.setThreadPool(
          new QueuedThreadPool(
              configsMap.getOptionInt("agent.threadpool.size.max", 25)));
      agentServer.setStopAtShutdown(true);

      SslSelectChannelConnector ssl1WayConnector = createSSLConnector(false);
      SslSelectChannelConnector ssl2WayConnector =
          createSSLConnector(Boolean.valueOf(
              configsMap.getOption("ssl.server.client.auth","false")));
      agentServer.setConnectors(new Connector[]{ssl1WayConnector,
          ssl2WayConnector});

      ServletHolder agent = new ServletHolder(new AgentServletContainer());
      Context agentRoot = new Context(agentServer, "/", Context.SESSIONS);

      agent.setInitParameter("com.sun.jersey.config.property.resourceConfigClass",
                             "com.sun.jersey.api.core.PackagesResourceConfig");
      agent.setInitParameter("com.sun.jersey.config.property.packages",
                             "org.apache.slider.server.appmaster.web.rest.agent");
      agent.setInitParameter("com.sun.jersey.api.json.POJOMappingFeature",
                             "true");
//      agent.setInitParameter("com.sun.jersey.spi.container.ContainerRequestFilters", "com.sun.jersey.api.container.filter.LoggingFilter");
//      agent.setInitParameter("com.sun.jersey.spi.container.ContainerResponseFilters", "com.sun.jersey.api.container.filter.LoggingFilter");
//      agent.setInitParameter("com.sun.jersey.config.feature.Trace", "true");
      agentRoot.addServlet(agent, "/*");

      try {
        agentServer.start();
      } catch (Exception e) {
        LOG.error("Unable to start agent server", e);
      }

      AgentWebApp webApp = new AgentWebApp();
      webApp.setPort(getConnectorPort(agentServer, 0));
      webApp.setSecuredPort(getConnectorPort(agentServer, 1));

      return webApp;

    }

    private SslSelectChannelConnector createSSLConnector(boolean needClientAuth) {
      SslSelectChannelConnector sslConnector = new
          SslSelectChannelConnector();

      String keystore = SecurityUtils.getSecurityDir() +
                        File.separator + "keystore.p12";
      String srvrCrtPass = SecurityUtils.getKeystorePass();
      sslConnector.setKeystore(keystore);
      sslConnector.setTruststore(keystore);
      sslConnector.setPassword(srvrCrtPass);
      sslConnector.setKeyPassword(srvrCrtPass);
      sslConnector.setTrustPassword(srvrCrtPass);
      sslConnector.setKeystoreType("PKCS12");
      sslConnector.setTruststoreType("PKCS12");
      sslConnector.setNeedClientAuth(needClientAuth);

      sslConnector.setAcceptors(2);
      return sslConnector;
    }

    @Provider
    public class WebAppApiProvider extends
        SingletonTypeInjectableProvider<javax.ws.rs.core.Context, WebAppApi> {

      public WebAppApiProvider () {
        super(WebAppApi.class, application);
      }
    }

    public class AgentServletContainer extends ServletContainer {
      public AgentServletContainer() {
        super();
      }

      @Override
      protected void configure(WebConfig wc,
                               ResourceConfig rc,
                               WebApplication wa) {
        super.configure(wc, rc, wa);
        Set<Object> singletons = rc.getSingletons();
        singletons.add(new WebAppApiProvider());
      }
    }

    private int getConnectorPort(Server webServer, int index) {
      Preconditions.checkArgument(index >= 0);
      if (index > webServer.getConnectors().length)
        throw new IllegalStateException("Illegal connect index requested");

      Connector c = webServer.getConnectors()[index];
      if (c.getLocalPort() == -1) {
        // The connector is not bounded
        throw new IllegalStateException("The connector is not bound to a port");
      }

      return c.getLocalPort();
    }
  }

  public static Builder $for(String name, WebAppApi app, String wsPrefix) {
    return new Builder(name, wsPrefix, app);
  }

  public int getPort() {
    return port;
  }

  public void setPort(int port) {
    this.port = port;
  }

  public void setSecuredPort(int securedPort) {
    this.securedPort = securedPort;
  }

  public int getSecuredPort() {
    return securedPort;
  }

  public void stop() {
    //need to stop server and reset injector
    try {
      agentServer.stop();
    } catch (Exception e) {
      LOG.warn("Unable to stop agent server", e);
    }
  }

}
