// Copyright (C) 2019 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.acceptance.rest.binding;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.rest.util.RestApiCallHelper;
import com.google.gerrit.acceptance.rest.util.RestCall;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.extensions.restapi.ChildCollection;
import com.google.gerrit.extensions.restapi.IdString;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.RestApiModule;
import com.google.gerrit.extensions.restapi.RestCollectionModifyView;
import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.extensions.restapi.RestResource;
import com.google.gerrit.extensions.restapi.RestView;
import com.google.gerrit.extensions.restapi.TopLevelResource;
import com.google.gerrit.httpd.restapi.RestApiServlet;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.google.inject.TypeLiteral;
import com.google.inject.servlet.ServletModule;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import org.junit.Test;

/**
 * Tests for checking plugin-provided REST API bindings directly under {@code /}.
 *
 * <p>These tests only verify that the plugin-provided REST endpoints are correctly bound, they do
 * not test the functionality of the plugin REST endpoints.
 */
public class PluginProvidedRootRestApiBindingsIT extends AbstractDaemonTest {

  /** Resource to bind a child collection. */
  public static final TypeLiteral<RestView<TestPluginResource>> TEST_KIND =
      new TypeLiteral<RestView<TestPluginResource>>() {};

  private static final String PLUGIN_NAME = "my-plugin";

  private static final ImmutableSet<RestCall> TEST_CALLS =
      ImmutableSet.of(
          RestCall.get("/plugins/" + PLUGIN_NAME + "/test-collection/"),
          RestCall.get("/plugins/" + PLUGIN_NAME + "/test-collection/1/detail"),
          RestCall.post("/plugins/" + PLUGIN_NAME + "/test-collection/"),
          RestCall.post("/plugins/" + PLUGIN_NAME + "/test-collection/1/update"));

  /** Module for all HTTP bindings. */
  static class MyPluginHttpModule extends ServletModule {
    @Override
    public void configureServlets() {
      bind(TestRootCollection.class);

      install(
          new RestApiModule() {
            @Override
            public void configure() {
              DynamicMap.mapOf(binder(), TEST_KIND);

              postOnCollection(TEST_KIND).to(TestPostOnCollection.class);
              post(TEST_KIND, "update").to(TestPost.class);
              get(TEST_KIND, "detail").to(TestGet.class);
            }
          });

      serveRegex("/(?:a/)?test-collection/(.*)$").with(TestRestApiServlet.class);
    }
  }

  @Singleton
  static class TestRestApiServlet extends RestApiServlet {
    private static final long serialVersionUID = 1L;

    @Inject
    TestRestApiServlet(RestApiServlet.Globals globals, Provider<TestRootCollection> collection) {
      super(globals, collection);
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse)
        throws ServletException, IOException {
      // This is...unfortunate. HttpPluginServlet (and/or ContextMapper) doesn't properly set the
      // servlet path on the wrapped request. Based on what RestApiServlet produces for non-plugin
      // requests, it should be:
      //   contextPath = "/plugins/checks"
      //   servletPath = "/checkers/"
      //   pathInfo = checkerUuid
      // Instead it does:
      //   contextPath = "/plugins/checks"
      //   servletPath = ""
      //   pathInfo = "/checkers/" + checkerUuid
      // This results in RestApiServlet splitting the pathInfo into ["", "checkers", checkerUuid],
      // and it passes the "" to CheckersCollection#parse, which understandably, but unfortunately,
      // fails.
      //
      // This frankly seems like a bug that should be fixed, but it would quite likely break
      // existing plugins in confusing ways. So, we work around it by introducing our own request
      // wrapper with the correct paths.
      HttpServletRequest req = (HttpServletRequest) servletRequest;
      String pathInfo = req.getPathInfo();
      String correctServletPath = "/test-collection/";
      String fixedPathInfo = pathInfo.substring(correctServletPath.length());
      HttpServletRequestWrapper wrapped =
          new HttpServletRequestWrapper(req) {
            @Override
            public String getServletPath() {
              return correctServletPath;
            }

            @Override
            public String getPathInfo() {
              return fixedPathInfo;
            }
          };

      super.service(wrapped, (HttpServletResponse) servletResponse);
    }
  }

  static class TestPluginResource implements RestResource {}

  @Singleton
  static class TestRootCollection implements ChildCollection<TopLevelResource, TestPluginResource> {
    private final DynamicMap<RestView<TestPluginResource>> views;

    @Inject
    TestRootCollection(DynamicMap<RestView<TestPluginResource>> views) {
      this.views = views;
    }

    @Override
    public RestView<TopLevelResource> list() throws RestApiException {
      return (RestReadView<TopLevelResource>) resource -> ImmutableList.of("one", "two");
    }

    @Override
    public TestPluginResource parse(TopLevelResource parent, IdString id) throws Exception {
      return new TestPluginResource();
    }

    @Override
    public DynamicMap<RestView<TestPluginResource>> views() {
      return views;
    }
  }

  @Singleton
  static class TestPostOnCollection
      implements RestCollectionModifyView<TopLevelResource, TestPluginResource, String> {
    @Override
    public Object apply(TopLevelResource parentResource, String input) throws Exception {
      return "test";
    }
  }

  @Singleton
  static class TestPost implements RestModifyView<TestPluginResource, String> {
    @Override
    public String apply(TestPluginResource resource, String input) throws Exception {
      return "test";
    }
  }

  @Singleton
  static class TestGet implements RestReadView<TestPluginResource> {
    @Override
    public String apply(TestPluginResource resource) throws Exception {
      return "test";
    }
  }

  @Test
  public void testEndpoints() throws Exception {
    try (AutoCloseable ignored = installPlugin(PLUGIN_NAME, null, MyPluginHttpModule.class, null)) {
      RestApiCallHelper.execute(adminRestSession, TEST_CALLS.asList());
    }
  }
}
