// Copyright (C) 2013 The Android Open Source Project
//
// Licensed 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 com.googlesource.gerrit.plugins.hooks.rtc.network;

import java.io.IOException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpResponse;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.DefaultRedirectHandler;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HttpContext;
import org.eclipse.jgit.lib.Config;

import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.inject.Inject;
import com.googlesource.gerrit.plugins.hooks.rtc.RTCItsFacade;
import com.googlesource.gerrit.plugins.hooks.rtc.api.RtcEntity;
import com.googlesource.gerrit.plugins.hooks.rtc.api.RtcEntityDeserializer;
import com.googlesource.gerrit.plugins.hooks.rtc.session.SessionApi;
import com.googlesource.gerrit.plugins.hooks.rtc.session.SessionApiImpl;
import com.googlesource.gerrit.plugins.hooks.rtc.workitems.RtcComment;
import com.googlesource.gerrit.plugins.hooks.rtc.workitems.RtcCommentDeserializer;
import com.googlesource.gerrit.plugins.hooks.rtc.workitems.RtcRelatedLink;
import com.googlesource.gerrit.plugins.hooks.rtc.workitems.RtcRelatedLinkDeserializer;
import com.googlesource.gerrit.plugins.hooks.rtc.workitems.RtcWorkItem;
import com.googlesource.gerrit.plugins.hooks.rtc.workitems.RtcWorkItemDeserializer;
import com.googlesource.gerrit.plugins.hooks.rtc.workitems.RtcWorkflowAction;
import com.googlesource.gerrit.plugins.hooks.rtc.workitems.RtcWorkflowActionDeserializer;
import com.googlesource.gerrit.plugins.hooks.rtc.workitems.WorkItemsApi;
import com.googlesource.gerrit.plugins.hooks.rtc.workitems.WorkItemsApiImpl;

public class RTCClient {

  private static Log LOG = LogFactory.getLog(RTCClient.class);

  private String baseUrl;
  private DefaultHttpClient httpclient;
  private BasicCookieStore cookieStore;
  private Gson gson;

  private Transport transport;
  private CachableResourcesFactory factory;

  private SessionApi sessionApi;
  private WorkItemsApi workItemsApi;

  private boolean loggedIn;

  private String rtcUser;

  private String rtcPassword;

  @Inject
  public RTCClient(@GerritServerConfig Config config, RTCHttpParams httpParams)
      throws IOException {
    this(config.getString(RTCItsFacade.ITS_NAME_RTC, null, "url"), config
        .getBoolean(RTCItsFacade.ITS_NAME_RTC, null, "sslVerify", true),
        httpParams);
  }

  public RTCClient(String url, boolean sslVerify, HttpParams httpParams)
      throws IOException {
    super();

    this.baseUrl = (url.endsWith("/") ? url.substring(url.length() - 1) : url);
    if (httpParams == null) {
      httpParams = new BasicHttpParams();
    }
    SchemeRegistry schemeRegistry = new SchemeRegistry();
    schemeRegistry.register(new Scheme("http", PlainSocketFactory
        .getSocketFactory(), 80));
    this.httpclient =
        new DefaultHttpClient(new ThreadSafeClientConnManager(httpParams,
            schemeRegistry), httpParams);

    this.transport = new Transport(this, baseUrl, httpclient, httpParams);
    this.factory = new CachableResourcesFactory(transport);

    GsonBuilder builder = new GsonBuilder();
    builder.registerTypeAdapter(RtcWorkItem.class, new RtcWorkItemDeserializer(
        factory));
    builder.registerTypeAdapter(RtcComment.class, new RtcCommentDeserializer());
    builder.registerTypeAdapter(RtcEntity.class, new RtcEntityDeserializer());
    builder.registerTypeAdapter(RtcRelatedLink.class,
        new RtcRelatedLinkDeserializer());
    builder.registerTypeAdapter(RtcWorkflowAction.class,
        new RtcWorkflowActionDeserializer());
    gson = builder.create();
    transport.setGson(gson);

    setCookieStore();
    setRedirectStategy();
    setSSLTrustStrategy(sslVerify);

    sessionApi = new SessionApiImpl(this, transport);
    workItemsApi = new WorkItemsApiImpl(this, transport);
  }

  public boolean isLoggedIn() {
    return loggedIn;
  }

  public SessionApi sessionApi() throws IOException {
    collectSessionCookie();
    return sessionApi;
  }

  public WorkItemsApi workItemsApi() throws IOException {
    collectSessionCookie();
    return workItemsApi;
  }

  private void collectSessionCookie() throws IOException {
    if (cookieStore.getCookies().size() <= 0) {
      LOG.debug("Initial collecting of session cookie...");
      transport.get(baseUrl);
      LOG.debug("Succesfully collected cookies: " + cookieStore.getCookies());
    }
  }

  private void setCookieStore() {
    cookieStore = new BasicCookieStore();
    httpclient.setCookieStore(cookieStore);
  }

  private void setSSLTrustStrategy(boolean sslVerify) throws IOException {
    try {
      TrustManager[] trustAllCerts =
          new TrustManager[] {new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() {
              return new X509Certificate[0];
            }

            public void checkClientTrusted(X509Certificate[] certs,
                String authType) {
            }

            public void checkServerTrusted(X509Certificate[] certs,
                String authType) {
            }
          }};
      SSLContext sc;

      if (sslVerify) {
        sc = SSLContext.getDefault();
      } else {
        sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new SecureRandom());
      }

      SSLSocketFactory sf = new SSLSocketFactory(sc);
      sf.setHostnameVerifier(new AllowAllHostnameVerifier());
      SchemeRegistry schemeRegistry =
          httpclient.getConnectionManager().getSchemeRegistry();
      schemeRegistry.register(new Scheme("https", sf, 443));
    } catch (Exception any) {
      throw new IOException(any);
    }
  }

  private void setRedirectStategy() {
    httpclient.setRedirectHandler(new DefaultRedirectHandler() {
      @Override
      public boolean isRedirectRequested(HttpResponse response,
          HttpContext context) {
        boolean isRedirect = super.isRedirectRequested(response, context);
        if (!isRedirect) {
          int responseCode = response.getStatusLine().getStatusCode();
          if (responseCode == 301 || responseCode == 302) {
            return true;
          }
        }
        return isRedirect;
      }
    });
  }

  public Transport getTransportForTest() {
    return transport;
  }

  public void setLoginCredentials(String rtcUser, String rtcPassword) throws IOException {
    this.rtcUser = rtcUser;
    this.rtcPassword = rtcPassword;
  }

  public void login() throws IOException {
    sessionApi().login(rtcUser, rtcPassword);
    loggedIn = true;
  }

  public void ping() throws IOException {
    if (loggedIn) {
      sessionApi().ping();
    }
  }

  public void setLoggedIn(boolean b) {
    loggedIn = false;
  }
}
