// Copyright (C) 2015 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.github.notification;

import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN;
import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.io.CharStreams;
import com.google.gerrit.extensions.registration.DynamicItem;
import com.google.gerrit.httpd.WebSession;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gson.Gson;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;
import com.googlesource.gerrit.plugins.github.GitHubConfig;
import com.googlesource.gerrit.plugins.github.oauth.GitHubLogin;
import com.googlesource.gerrit.plugins.github.oauth.ScopedProvider;
import com.googlesource.gerrit.plugins.github.oauth.UserScopedProvider;
/**
 * Handles webhook callbacks sent from Github. Delegates requests to
 * implementations of {@link WebhookEventHandler}.
 */
@Singleton
public class WebhookServlet extends HttpServlet {
  private static final long serialVersionUID = 1L;
  private static final Logger logger =
      LoggerFactory.getLogger(WebhookServlet.class);

  private static final String PACKAGE_NAME =
      WebhookServlet.class.getPackage().getName();
  private static final String SIGNATURE_PREFIX = "sha1=";
  private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1";

  private final Gson gson;

  private final Map<String, WebhookEventHandler<?>> handlerByName =
      new ConcurrentHashMap<>();
  private final Injector injector;
  private final GitHubConfig config;

  private final UserScopedProvider<GitHubLogin> loginProvider;
  private final ScopedProvider<GitHubLogin> requestScopedLoginProvider;
  private final DynamicItem<WebSession> session;

  @Inject
  public WebhookServlet(UserScopedProvider<GitHubLogin> loginProvider,
      ScopedProvider<GitHubLogin> requestScopedLoginProvider,
      GitHubConfig config, Gson gson, DynamicItem<WebSession> session,
      Injector injector) {
    this.loginProvider = loginProvider;
    this.requestScopedLoginProvider = requestScopedLoginProvider;
    this.injector = injector;
    this.config = config;
    this.gson = gson;
    this.session = session;
  }

  private WebhookEventHandler<?> getWebhookHandler(String name) {
    if (name == null) {
      logger.error("Null event name: cannot find any handler for it");
      return null;
    }

    WebhookEventHandler<?> handler = handlerByName.get(name);
    if (handler != null) {
      return handler;
    }

    try {
      String className = eventClassName(name);
      Class<?> clazz = Class.forName(className);
      handler = (WebhookEventHandler<?>) injector.getInstance(clazz);
      handlerByName.put(name, handler);
      logger.info("Loaded {}", clazz.getName());
    } catch (ClassNotFoundException e) {
      logger.error("Handler '" + name + "' not found. Skipping", e);
    }

    return handler;
  }

  private String eventClassName(String name) {
    String[] nameParts = name.split("_");
    List<String> classNameParts =
        Lists.transform(Arrays.asList(nameParts),
            new Function<String, String>() {
              @Override
              public String apply(String part) {
                return Character.toUpperCase(part.charAt(0))
                    + part.substring(1);
              }
            });
    return PACKAGE_NAME + "." + Joiner.on("").join(classNameParts)
        + "Handler";
  }

  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {
    if (Strings.emptyToNull(config.webhookUser) == null) {
      logger.error("No webhookUser defined: cannot process GitHub events");
      resp.sendError(SC_INTERNAL_SERVER_ERROR);
      return;
    }

    WebhookEventHandler<?> handler =
        getWebhookHandler(req.getHeader("X-Github-Event"));
    if (handler == null) {
      resp.sendError(SC_NOT_FOUND);
      return;
    }

    BufferedReader reader = req.getReader();
    String body = Joiner.on("\n").join(CharStreams.readLines(reader));
    if (!validateSignature(req.getHeader("X-Hub-Signature"), body,
        req.getCharacterEncoding())) {
      logger.error("Signature mismatch to the payload");
      resp.sendError(SC_FORBIDDEN);
      return;
    }

    session.get().setUserAccountId(Account.Id.fromRef(config.webhookUser));
    GitHubLogin login = loginProvider.get(config.webhookUser);
    if (login == null || !login.isLoggedIn()) {
      logger.error(
          "Cannot login to github as {}. {}.webhookUser is not correctly configured?",
          config.webhookUser, GitHubConfig.CONF_SECTION);
      resp.setStatus(SC_INTERNAL_SERVER_ERROR);
      return;
    }
    requestScopedLoginProvider.get(req).login(login.getToken());

    if (callHander(handler, body)) {
      resp.setStatus(SC_NO_CONTENT);
    } else {
      resp.sendError(SC_INTERNAL_SERVER_ERROR);
    }
  }

  private <T> boolean callHander(WebhookEventHandler<T> handler, String jsonBody)
      throws IOException {
    T payload = gson.fromJson(jsonBody, handler.getPayloadType());
    if (payload != null) {
      return handler.doAction(payload);
    } else {
      logger.error("Cannot decode JSON payload '" + jsonBody + "' into "
          + handler.getPayloadType().getName());
      return false;
    }
  }

  /**
   * validates callback signature sent from github
   *
   * @param signatureHeader signature HTTP request header of a github webhook
   * @param payload HTTP request body
   * @return true if webhook secret is not configured or signatureHeader is
   *         valid against payload and the secret, false if otherwise.
   * @throws UnsupportedEncodingException
   */
  private boolean validateSignature(String signatureHeader, String body,
      String encoding) throws UnsupportedEncodingException {
    byte[] payload = body.getBytes(encoding == null ? "UTF-8" : encoding);
    if (config.webhookSecret == null || config.webhookSecret.equals("")) {
      logger.debug("{}.webhookSecret not configured. Skip signature validation",
          GitHubConfig.CONF_SECTION);
      return true;
    }

    if (!StringUtils.startsWith(signatureHeader, SIGNATURE_PREFIX)) {
      logger.error("Unsupported webhook signature type: {}", signatureHeader);
      return false;
    }
    byte[] signature;
    try {
      signature = Hex.decodeHex(
          signatureHeader.substring(SIGNATURE_PREFIX.length()).toCharArray());
    } catch (DecoderException e) {
      logger.error("Invalid signature: {}", signatureHeader);
      return false;
    }
    return MessageDigest.isEqual(signature, getExpectedSignature(payload));
  }

  /**
   * Calculates the expected signature of the payload
   *
   * @param payload payload to calculate a signature for
   * @return signature of the payload
   * @see <a href=
   *      "https://developer.github.com/webhooks/securing/#validating-payloads-from-github">
   *      Validating payloads from GitHub</a>
   */
  private byte[] getExpectedSignature(byte[] payload) {
    SecretKeySpec key =
        new SecretKeySpec(config.webhookSecret.getBytes(), HMAC_SHA1_ALGORITHM);
    Mac hmac;
    try {
      hmac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
      hmac.init(key);
    } catch (NoSuchAlgorithmException e) {
      throw new IllegalStateException("Hmac SHA1 must be supported", e);
    } catch (InvalidKeyException e) {
      throw new IllegalStateException(
          "Hmac SHA1 must be compatible to Hmac SHA1 Secret Key", e);
    }
    return hmac.doFinal(payload);
  }
}
