// Copyright (C) 2008 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.google.gerrit.httpd.rpc;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import com.google.gerrit.audit.AuditService;
import com.google.gerrit.audit.RpcAuditEvent;
import com.google.gerrit.common.audit.Audit;
import com.google.gerrit.common.auth.SignInRequired;
import com.google.gerrit.common.errors.NotSignedInException;
import com.google.gerrit.httpd.WebSession;
import com.google.gerrit.server.AccessPath;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.util.TimeUtil;
import com.google.gson.GsonBuilder;
import com.google.gwtjsonrpc.common.RemoteJsonService;
import com.google.gwtjsonrpc.server.ActiveCall;
import com.google.gwtjsonrpc.server.JsonServlet;
import com.google.gwtjsonrpc.server.MethodHandle;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

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

/**
 * Base JSON servlet to ensure the current user is not forged.
 */
@SuppressWarnings("serial")
final class GerritJsonServlet extends JsonServlet<GerritJsonServlet.GerritCall> {
  private static final Logger log = LoggerFactory.getLogger(GerritJsonServlet.class);
  private static final ThreadLocal<GerritCall> currentCall =
      new ThreadLocal<GerritCall>();
  private static final ThreadLocal<MethodHandle> currentMethod =
      new ThreadLocal<MethodHandle>();
  private final Provider<WebSession> session;
  private final RemoteJsonService service;
  private final AuditService audit;


  @Inject
  GerritJsonServlet(final Provider<WebSession> w, final RemoteJsonService s,
      final AuditService a) {
    session = w;
    service = s;
    audit = a;
  }

  @Override
  protected GerritCall createActiveCall(final HttpServletRequest req,
      final HttpServletResponse rsp) {
    final GerritCall call = new GerritCall(session.get(), req, new AuditedHttpServletResponse(rsp));
    currentCall.set(call);
    return call;
  }

  @Override
  protected GsonBuilder createGsonBuilder() {
    return gerritDefaultGsonBuilder();
  }

  private static GsonBuilder gerritDefaultGsonBuilder() {
    final GsonBuilder g = defaultGsonBuilder();

    g.registerTypeAdapter(org.eclipse.jgit.diff.Edit.class,
        new org.eclipse.jgit.diff.EditDeserializer());

    return g;
  }

  @Override
  protected void preInvoke(final GerritCall call) {
    super.preInvoke(call);

    if (call.isComplete()) {
      return;
    }

    if (call.getMethod().getAnnotation(SignInRequired.class) != null) {
      // If SignInRequired is set on this method we must have both a
      // valid XSRF token *and* have the user signed in. Doing these
      // checks also validates that they agree on the user identity.
      //
      if (!call.requireXsrfValid() || !session.get().isSignedIn()) {
        call.onFailure(new NotSignedInException());
      }
    }
  }

  @Override
  protected Object createServiceHandle() {
    return service;
  }

  @Override
  protected void service(final HttpServletRequest req,
      final HttpServletResponse resp) throws IOException {
    try {
      super.service(req, resp);
    } finally {
      audit();
      currentCall.set(null);
    }
  }

  private void audit() {
    try {
      GerritCall call = currentCall.get();
      MethodHandle method = call.getMethod();
      if (method == null) {
        return;
      }
      Audit note = (Audit) method.getAnnotation(Audit.class);
      if (note != null) {
        final String sid = call.getWebSession().getSessionId();
        final CurrentUser username = call.getWebSession().getCurrentUser();
        final Multimap<String, ?> args =
            extractParams(note, call);
        final String what = extractWhat(note, call);
        final Object result = call.getResult();

        audit.dispatch(new RpcAuditEvent(sid, username, what, call.getWhen(),
            args, call.getHttpServletRequest().getMethod(), call.getHttpServletRequest().getMethod(),
            ((AuditedHttpServletResponse) (call.getHttpServletResponse()))
                .getStatus(), result));
      }
    } catch (Throwable all) {
      log.error("Unable to log the call", all);
    }
  }

  private Multimap<String, ?> extractParams(final Audit note, final GerritCall call) {
    Multimap<String, Object> args = ArrayListMultimap.create();

    Object[] params = call.getParams();
    for (int i = 0; i < params.length; i++) {
      args.put("$" + i, params[i]);
    }

    for (int idx : note.obfuscate()) {
      args.removeAll("$" + idx);
      args.put("$" + idx, "*****");
    }
    return args;
  }

  private String extractWhat(final Audit note, final GerritCall call) {
    String methodClass = call.getMethodClass().getName();
    methodClass = methodClass.substring(methodClass.lastIndexOf(".")+1);
    String what = note.action();
    if (what.length() == 0) {
      what = call.getMethod().getName();
    }

    return methodClass + "." + what;
  }

  static class GerritCall extends ActiveCall {
    private final WebSession session;
    private final long when;
    private static final Field resultField;
    private static final Field methodField;

    // Needed to allow access to non-public result field in GWT/JSON-RPC
    static {
      resultField = getPrivateField(ActiveCall.class, "result");
      methodField = getPrivateField(MethodHandle.class, "method");
    }

    private static Field getPrivateField(Class<?> clazz, String fieldName) {
      Field declaredField = null;
      try {
        declaredField = clazz.getDeclaredField(fieldName);
        declaredField.setAccessible(true);
      } catch (Exception e) {
        log.error("Unable to expose RPS/JSON result field");
      }
      return declaredField;
    }

    // Surrogate of the missing getMethodClass() in GWT/JSON-RPC
    public Class<?> getMethodClass() {
      if (methodField == null) {
        return null;
      }

      try {
        Method method = (Method) methodField.get(this.getMethod());
        return method.getDeclaringClass();
      } catch (IllegalArgumentException e) {
        log.error("Cannot access result field");
      } catch (IllegalAccessException e) {
        log.error("No permissions to access result field");
      }

      return null;
    }

    // Surrogate of the missing getResult() in GWT/JSON-RPC
    public Object getResult() {
      if (resultField == null) {
        return null;
      }

      try {
        return resultField.get(this);
      } catch (IllegalArgumentException e) {
        log.error("Cannot access result field");
      } catch (IllegalAccessException e) {
        log.error("No permissions to access result field");
      }

      return null;
    }

    GerritCall(final WebSession session, final HttpServletRequest i,
        final HttpServletResponse o) {
      super(i, o);
      this.session = session;
      this.when = TimeUtil.nowMs();
    }

    @Override
    public MethodHandle getMethod() {
      if (currentMethod.get() == null) {
        return super.getMethod();
      } else {
        return currentMethod.get();
      }
    }

    @Override
    public void onFailure(final Throwable error) {
      if (error instanceof IllegalArgumentException
          || error instanceof IllegalStateException) {
        super.onFailure(error);
      } else if (error instanceof OrmException
          || error instanceof RuntimeException) {
        onInternalFailure(error);
      } else {
        super.onFailure(error);
      }
    }

    @Override
    public boolean xsrfValidate() {
      final String keyIn = getXsrfKeyIn();
      if (keyIn == null || "".equals(keyIn)) {
        // Anonymous requests don't need XSRF protection, they shouldn't
        // be able to cause critical state changes.
        //
        return !session.isSignedIn();

      } else if (session.isSignedIn() && session.isValidXGerritAuth(keyIn)) {
        // The session must exist, and must be using this token.
        //
        session.getCurrentUser().setAccessPath(AccessPath.JSON_RPC);
        return true;
      }
      return false;
    }

    public WebSession getWebSession() {
      return session;
    }

    public long getWhen() {
      return when;
    }

    public long getElapsed() {
      return TimeUtil.nowMs() - when;
    }
  }

}
