/*
 * 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.providers.agent.AgentKeys;
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.Closeable;
import java.io.File;
import java.io.IOException;
import java.util.Set;

/**
 *
 */
public class AgentWebApp implements Closeable {
  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() throws IOException {
      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(AgentKeys.KEY_AGENT_TWO_WAY_SSL_ENABLED,
                                   "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 (IOException e) {
        LOG.error("Unable to start agent server", e);
        throw e;
      } catch (Exception e) {
        LOG.error("Unable to start agent server", e);
        throw new IOException("Unable to start agent server: " + e, 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 close() throws IOException{
    //need to stop server and reset injector
    try {
      agentServer.stop();
    } catch (IOException e) {
      throw e;
    } catch (Exception e) {
      throw new IOException(e.toString(), e);
    }
  }

}
