// 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 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;
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;
/**
 * 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;
    }

    try (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);
    }
    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);
  }
}
