package com.googlesource.gerrit.plugins.github.oauth;

import com.google.common.base.Charsets;
import com.google.common.base.Strings;
import com.google.common.io.BaseEncoding;
import com.google.common.io.CharStreams;
import com.google.gson.Gson;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.gerrit.extensions.auth.oauth.OAuthToken;
import com.google.gerrit.extensions.auth.oauth.OAuthVerifier;

@Singleton
public class OAuthProtocol {
  /**
   * Supported OAuth Scopes.
   *
   * OAuth authorization scopes as defined in GitHub API at:
   * https://developer.github.com/v3/oauth/#scopes
   */
  public static enum Scope {
    /**
     * Grants read-only access to public information (includes public user
     * profile info, public repository info, and gists)
     */
    DEFAULT(""),

    /**
     * Grants read/write access to profile info only. Note that this scope
     * includes user:email and user:follow.
     */
    USER("user"),

    /**
     * Grants read access to a user’s email addresses.
     */
    USER_EMAIL("user:email"),

    /**
     * Grants access to follow or unfollow other users.
     */
    USER_FOLLOW("user:follow"),

    /**
     * Grants read/write access to code, commit statuses, collaborators, and
     * deployment statuses for public repositories and organizations. Also
     * required for starring public repositories.
     */
    PUBLIC_REPO("public_repo"),

    /**
     * Grants read/write access to code, commit statuses, collaborators, and
     * deployment statuses for public and private repositories and
     * organizations.
     */
    REPO("repo"),

    /**
     * Grants access to deployment statuses for public and private repositories.
     * This scope is only necessary to grant other users or services access to
     * deployment statuses, without granting access to the code.
     */
    REPO_DEPLOYMENT("repo_deployment"),

    /**
     * Grants read/write access to public and private repository commit
     * statuses. This scope is only necessary to grant other users or services
     * access to private repository commit statuses without granting access to
     * the code.
     */
    REPO_STATUS("repo:status"),

    /**
     * Grants access to delete admin-able repositories.
     */
    DELETE_REPO("delete_repo"),

    /**
     * Grants read access to a user’s notifications. repo also provides this
     * access.
     */
    NOTIFICATIONS("notifications"),

    /**
     * Grants write access to gists.
     */
    GIST("gist"),

    /**
     * Grants read and ping access to hooks in public or private repositories.
     */
    READ_REPO_HOOK("read:repo_hook"),

    /**
     * Grants read, write, and ping access to hooks in public or private
     * repositories.
     */
    WRITE_REPO_HOOK("write:repo_hook"),

    /**
     * Grants read, write, ping, and delete access to hooks in public or private
     * repositories.
     */
    ADMIN_REPO_HOOK("admin:repo_hook"),

    /**
     * Grants read, write, ping, and delete access to organization hooks. Note:
     * OAuth tokens will only be able to perform these actions on organization
     * hooks which were created by the OAuth application. Personal access tokens
     * will only be able to perform these actions on organization hooks created
     * by a user.
     */
    ADMIN_ORG_HOOK("admin:org_hook"),

    /**
     * Read-only access to organization, teams, and membership.
     */
    READ_ORG("read:org"),

    /**
     * Publicize and un-publicize organization membership.
     */
    WRITE_ORG("write:org"),

    /**
     * Fully manage organization, teams, and memberships.
     */
    ADMIN_ORG("admin:org"),

    /**
     * List and view details for public keys.
     */
    READ_PUBLIC_KEY("read:public_key"),

    /**
     * Create, list, and view details for public keys.
     */
    WRITE_PUBLIC_KEY("write:public_key"),

    /**
     * Fully manage public keys.
     */
    ADMIN_PUBLIC_KEY("admin:public_key");

    private final String value;

    public String getValue() {
      return value;
    }

    private Scope(final String value) {
      this.value = value;
    }
  }
  private static final String ME_SEPARATOR = ",";
  private static final Logger log = LoggerFactory
      .getLogger(OAuthProtocol.class);
  private static SecureRandom randomState = newRandomGenerator();

  private final GitHubOAuthConfig config;
  private final Gson gson;
  private final Provider<HttpClient> httpProvider;

  public static class AccessToken {
    public String accessToken;
    public String tokenType;
    public String error;
    public String errorDescription;
    public String errorUri;
    public String raw;

    public AccessToken() {
    }

    public AccessToken(String token) {
      this(token, "");
    }

    public AccessToken(String token, String type) {
      this();
      this.accessToken = token;
      this.tokenType = type;
    }

    @Override
    public String toString() {
      if (isError()) {
        return "Error AccessToken [error=" + error + ", error_description="
            + errorDescription + ", error_uri=" + errorUri + "]";
      } else {
        return "AccessToken [access_token=" + accessToken + ", token_type="
            + tokenType + "]";
      }
    }

    @Override
    public int hashCode() {
      return Objects.hash(accessToken, tokenType, error, errorDescription,
          errorUri);
    }

    @Override
    public boolean equals(Object obj) {
      return Objects.deepEquals(this, obj);
    }

    public boolean isError() {
      return !Strings.isNullOrEmpty(error);
    }

    public String getRaw() {
      return raw;
    }

    public void setRaw(String raw) {
      this.raw = raw;
    }

    public OAuthToken toOAuthToken() {
      return new OAuthToken(accessToken, null, getRaw());
    }
  }

  @Inject
  public OAuthProtocol(GitHubOAuthConfig config,
      PooledHttpClientProvider httpClientProvider,
      /*
       * We need to explicitly tell Guice which Provider<> we need as this class
       * may be instantiated outside the standard Guice Module set-up (e.g.
       * initial Servlet login filter)
       */
      GsonProvider gsonProvider) {
    this.config = config;
    this.httpProvider = httpClientProvider;
    this.gson = gsonProvider.get();
  }

  private static SecureRandom newRandomGenerator() {
    try {
      return SecureRandom.getInstance("SHA1PRNG");
    } catch (NoSuchAlgorithmException e) {
      throw new IllegalArgumentException(
          "No SecureRandom available for GitHub authentication", e);
    }
  }

  public String getAuthorizationUrl(String scopesString, String state) {
    return config.gitHubOAuthUrl + "?client_id=" + config.gitHubClientId
        + getURLEncodedParameter("&scope=", scopesString)
        + getURLEncodedParameter("&redirect_uri=", config.oAuthFinalRedirectUrl)
        + getURLEncodedParameter("&state=", state);
  }

  public String loginPhase1(HttpServletRequest request,
      HttpServletResponse response, Set<Scope> scopes) throws IOException {
    String scopesString = getScope(scopes);
    log.debug("Initiating GitHub Login for ClientId=" + config.gitHubClientId
        + " Scopes=" + scopesString);
    String state = newRandomState(request.getRequestURI().toString());
    log.debug("Initiating GitHub Login for ClientId=" + config.gitHubClientId + " Scopes=" + scopesString);
    response.sendRedirect(getAuthorizationUrl(scopesString, state));
    return state;
  }

  public String getScope(Set<Scope> scopes) {
    if(scopes.size() <= 0) {
      return "";
    }

    StringBuilder out = new StringBuilder();
    for (Scope scope : scopes) {
      if (out.length() > 0) {
        out.append(",");
      }
      out.append(scope.getValue());
    }
    return out.toString();
  }

  public static boolean isOAuthFinal(HttpServletRequest request) {
    return Strings.emptyToNull(request.getParameter("code")) != null;
  }

  public static boolean isOAuthFinalForOthers(HttpServletRequest request) {
    String targetUrl = getTargetUrl(request);
    if(targetUrl.equals(request.getRequestURI())) {
      return false;
    }
    
    return Strings.emptyToNull(request.getParameter("code")) != null;
  }

  public String newRandomState(String redirectUrl) {
    byte[] stateBin = new byte[20]; // SHA-1 size
    randomState.nextBytes(stateBin);
    return BaseEncoding.base64Url().encode(stateBin) + ME_SEPARATOR + redirectUrl;
  }

  public static boolean isOAuthLogin(HttpServletRequest request) {
    return request.getRequestURI().indexOf(GitHubOAuthConfig.GERRIT_LOGIN) >= 0;
  }

  public static boolean isOAuthLogout(HttpServletRequest request) {
    return request.getRequestURI().indexOf(GitHubOAuthConfig.GERRIT_LOGOUT) >= 0;
  }

  public static boolean isOAuthRequest(HttpServletRequest httpRequest) {
    return OAuthProtocol.isOAuthLogin(httpRequest) || OAuthProtocol.isOAuthFinal(httpRequest);
  }

  public AccessToken loginPhase2(HttpServletRequest request,
      HttpServletResponse response, String state) throws IOException {
    String requestState = request.getParameter("state");
    if (!Objects.equals(state, requestState)) {
      throw new IOException("Invalid authentication state");
    }

    return getAccessToken(new OAuthVerifier(request.getParameter("code")));
  }

  public AccessToken getAccessToken(OAuthVerifier code) throws IOException {
    HttpPost post = new HttpPost(config.gitHubOAuthAccessTokenUrl);
    post.setHeader("Accept", "application/json");
    List<NameValuePair> nvps = new ArrayList<NameValuePair>();
    nvps.add(new BasicNameValuePair("client_id", config.gitHubClientId));
    nvps.add(new BasicNameValuePair("client_secret", config.gitHubClientSecret));
    nvps.add(new BasicNameValuePair("code", code.getValue()));
    post.setEntity(new UrlEncodedFormEntity(nvps, Charsets.UTF_8));

    HttpResponse postResponse = httpProvider.get().execute(post);
    if (postResponse.getStatusLine().getStatusCode() != HttpURLConnection.HTTP_OK) {
      log.error("POST " + config.gitHubOAuthAccessTokenUrl
          + " request for access token failed with status "
          + postResponse.getStatusLine());
      EntityUtils.consume(postResponse.getEntity());
      throw new IOException("GitHub OAuth request failed");
    }

    InputStream content = postResponse.getEntity().getContent();
    String tokenJsonString =
        CharStreams.toString(new InputStreamReader(content,
            StandardCharsets.UTF_8));
    AccessToken token = gson.fromJson(tokenJsonString, AccessToken.class);
    if (token.isError()) {
      log.error("POST " + config.gitHubOAuthAccessTokenUrl
          + " returned an error token: " + token);
      throw new IOException("Invalid GitHub OAuth token");
    }

    return token;
  }

  private static String getURLEncodedParameter(String prefix, String url) {
    try {
      return Strings.isNullOrEmpty(url) ? 
          "" : (prefix + URLEncoder.encode(url,"UTF-8"));
    } catch (UnsupportedEncodingException e) {
      throw new IllegalStateException("Cannot find UTF-8 encoding", e);
    }
  }

  public static String getTargetUrl(ServletRequest request) {
    int meEnd = state(request).indexOf(ME_SEPARATOR);
    if (meEnd > 0) {
      return state(request).substring(meEnd + 1);
    } else {
      return "";
    }
  }

  private static String state(ServletRequest request) {
    return Strings.nullToEmpty(request.getParameter("state"));
  }

  public static String getTargetOAuthFinal(HttpServletRequest httpRequest) {
    String targetUrl = getTargetUrl(httpRequest);
    String code = getURLEncodedParameter("code=", httpRequest.getParameter("code"));
    String state = getURLEncodedParameter("&state=", httpRequest.getParameter("state"));
    return targetUrl + (targetUrl.indexOf('?') < 0 ? '?' : '&') + code + state;
  }

  @Override
  public String toString() {
    return "OAuthProtocol";
  }

}
