// Copyright (C) 2021 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.pgm.http.jetty;

import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;

import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.AccountLimits;
import com.google.gerrit.server.account.GroupMembership;
import com.google.gerrit.server.git.QueueProvider;
import com.google.inject.Provider;
import java.util.Optional;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.eclipse.jetty.server.Request;
import org.eclipse.jgit.lib.Config;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class ProjectQoSFilterTest {

  @Mock AsyncEvent asyncEvent;
  @Mock AsyncContext asyncContext;

  @Mock AccountLimits.Factory limitsFactory;
  @Mock Provider<CurrentUser> userProvider;
  @Mock QueueProvider queue;
  @Mock ServletContext context;

  @Test
  public void shouldCallTaskEndOnListenerCompleteFromDifferentThread() {
    ProjectQoSFilter.TaskThunk taskThunk = getTaskThunk();
    ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1);

    Future<?> f = scheduledThreadPoolExecutor.submit(taskThunk);
    taskThunk.begin(Thread.currentThread());

    new Thread() {
      @Override
      public void run() {
        ProjectQoSFilter.Listener listener = new ProjectQoSFilter.Listener(f, taskThunk);
        try {
          listener.onComplete(asyncEvent);
        } catch (Exception e) {
        }
      }
    }.run();

    assertThat(taskThunk.isDone()).isTrue();
  }

  @Test
  public void shouldCallTaskEndOnListenerTimeoutFromDifferentThread() {
    ProjectQoSFilter.TaskThunk taskThunk = getTaskThunk();
    ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1);

    Future<?> f = scheduledThreadPoolExecutor.submit(taskThunk);
    taskThunk.begin(Thread.currentThread());

    new Thread() {
      @Override
      public void run() {
        ProjectQoSFilter.Listener listener = new ProjectQoSFilter.Listener(f, taskThunk);
        try {
          listener.onTimeout(asyncEvent);
        } catch (Exception e) {
        }
      }
    }.run();

    assertThat(taskThunk.isDone()).isTrue();
  }

  @Test
  public void shouldCallTaskEndOnListenerErrorFromDifferentThread() {
    ProjectQoSFilter.TaskThunk taskThunk = getTaskThunk();
    ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1);

    Future<?> f = scheduledThreadPoolExecutor.submit(taskThunk);
    taskThunk.begin(Thread.currentThread());

    new Thread() {
      @Override
      public void run() {
        ProjectQoSFilter.Listener listener = new ProjectQoSFilter.Listener(f, taskThunk);
        try {
          listener.onError(asyncEvent);
        } catch (Exception e) {
        }
      }
    }.run();

    assertThat(taskThunk.isDone()).isTrue();
  }

  private ProjectQoSFilter.TaskThunk getTaskThunk() {
    HttpServletRequest servletRequest = new FakeHttpServletRequest();
    Config config = new Config();
    String HTTP_MAX_WAIT = "1 minute";
    config.setString("httpd", null, "maxwait", HTTP_MAX_WAIT);

    when(userProvider.get()).thenReturn(new FakeUser("testUser"));
    when(asyncContext.getRequest()).thenReturn(servletRequest);

    ProjectQoSFilter projectQoSFilter =
        new ProjectQoSFilter(limitsFactory, userProvider, queue, context, config);
    return projectQoSFilter.new TaskThunk(asyncContext, servletRequest);
  }

  private static class FakeUser extends CurrentUser {
    private final String username;

    FakeUser(String name) {
      username = name;
    }

    @Override
    public GroupMembership getEffectiveGroups() {
      return null;
    }

    @Override
    public Object getCacheKey() {
      return new Object();
    }

    @Override
    public Optional<String> getUserName() {
      return Optional.ofNullable(username);
    }
  }

  private static final class FakeHttpServletRequest extends HttpServletRequestWrapper {

    FakeHttpServletRequest() {
      super(new Request(null, null));
    }

    @Override
    public String getRemoteHost() {
      return "1.2.3.4";
    }

    @Override
    public String getRemoteUser() {
      return "bob";
    }

    @Override
    public String getServletPath() {
      return "http://testulr/a/plugins_replication/info/refs?service=git-upload-pack";
    }
  }
}
