// Copyright (C) 2012 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.plugins;

import com.google.common.collect.Maps;
import com.google.gerrit.common.Version;
import com.google.gerrit.server.plugins.Plugin;
import java.io.InputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.URL;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

class PluginServletContext {
  private static final Logger log = LoggerFactory.getLogger(PluginServletContext.class);

  static ServletContext create(Plugin plugin, String contextPath) {
    return (ServletContext)
        Proxy.newProxyInstance(
            PluginServletContext.class.getClassLoader(),
            new Class<?>[] {ServletContext.class, API.class},
            new Handler(plugin, contextPath));
  }

  private PluginServletContext() {}

  private static class Handler implements InvocationHandler, API {
    private final Plugin plugin;
    private final String contextPath;
    private final ConcurrentMap<String, Object> attributes;

    Handler(Plugin plugin, String contextPath) {
      this.plugin = plugin;
      this.contextPath = contextPath;
      this.attributes = Maps.newConcurrentMap();
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
      Method handler;
      try {
        handler = API.class.getDeclaredMethod(method.getName(), method.getParameterTypes());
      } catch (NoSuchMethodException e) {
        throw new NoSuchMethodError(
            String.format(
                "%s does not implement %s", PluginServletContext.class, method.toGenericString()));
      }
      return handler.invoke(this, args);
    }

    @Override
    public String getContextPath() {
      return contextPath;
    }

    @Override
    public String getInitParameter(String name) {
      return null;
    }

    @SuppressWarnings("rawtypes")
    @Override
    public Enumeration getInitParameterNames() {
      return Collections.enumeration(Collections.emptyList());
    }

    @Override
    public ServletContext getContext(String name) {
      return null;
    }

    @Override
    public RequestDispatcher getNamedDispatcher(String name) {
      return null;
    }

    @Override
    public RequestDispatcher getRequestDispatcher(String name) {
      return null;
    }

    @Override
    public URL getResource(String name) {
      return null;
    }

    @Override
    public InputStream getResourceAsStream(String name) {
      return null;
    }

    @SuppressWarnings("rawtypes")
    @Override
    public Set getResourcePaths(String name) {
      return null;
    }

    @Override
    public Servlet getServlet(String name) {
      return null;
    }

    @Override
    public String getRealPath(String name) {
      return null;
    }

    @Override
    public String getServletContextName() {
      return plugin.getName();
    }

    @SuppressWarnings("rawtypes")
    @Override
    public Enumeration getServletNames() {
      return Collections.enumeration(Collections.emptyList());
    }

    @SuppressWarnings("rawtypes")
    @Override
    public Enumeration getServlets() {
      return Collections.enumeration(Collections.emptyList());
    }

    @Override
    public void log(Exception reason, String msg) {
      log(msg, reason);
    }

    @Override
    public void log(String msg) {
      log(msg, null);
    }

    @Override
    public void log(String msg, Throwable reason) {
      log.warn("[plugin {}] {}", plugin.getName(), msg, reason);
    }

    @Override
    public Object getAttribute(String name) {
      return attributes.get(name);
    }

    @Override
    public Enumeration<String> getAttributeNames() {
      return Collections.enumeration(attributes.keySet());
    }

    @Override
    public void setAttribute(String name, Object value) {
      attributes.put(name, value);
    }

    @Override
    public void removeAttribute(String name) {
      attributes.remove(name);
    }

    @Override
    public String getMimeType(String file) {
      return null;
    }

    @Override
    public int getMajorVersion() {
      return 2;
    }

    @Override
    public int getMinorVersion() {
      return 5;
    }

    @Override
    public String getServerInfo() {
      String v = Version.getVersion();
      return "Gerrit Code Review/" + (v != null ? v : "dev");
    }
  }

  interface API {
    String getContextPath();

    String getInitParameter(String name);

    @SuppressWarnings("rawtypes")
    Enumeration getInitParameterNames();

    ServletContext getContext(String name);

    RequestDispatcher getNamedDispatcher(String name);

    RequestDispatcher getRequestDispatcher(String name);

    URL getResource(String name);

    InputStream getResourceAsStream(String name);

    @SuppressWarnings("rawtypes")
    Set getResourcePaths(String name);

    Servlet getServlet(String name);

    String getRealPath(String name);

    String getServletContextName();

    @SuppressWarnings("rawtypes")
    Enumeration getServletNames();

    @SuppressWarnings("rawtypes")
    Enumeration getServlets();

    void log(Exception reason, String msg);

    void log(String msg);

    void log(String msg, Throwable reason);

    Object getAttribute(String name);

    Enumeration<String> getAttributeNames();

    void setAttribute(String name, Object value);

    void removeAttribute(String name);

    String getMimeType(String file);

    int getMajorVersion();

    int getMinorVersion();

    String getServerInfo();
  }
}
