// 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.googlesource.gerrit.plugins.healthcheck.check;

import static com.googlesource.gerrit.plugins.healthcheck.check.HealthCheckNames.BLOCKEDTHREADS;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.gerrit.extensions.config.FactoryModule;
import com.google.inject.Inject;
import com.google.inject.Module;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.googlesource.gerrit.plugins.healthcheck.HealthCheckConfig;
import com.googlesource.gerrit.plugins.healthcheck.HealthCheckMetrics;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;

@Singleton
public class BlockedThreadsCheck extends AbstractHealthCheck {
  public static Module SUB_CHECKS =
      new FactoryModule() {
        @Override
        protected void configure() {
          factory(BlockedThreadsSubCheck.Factory.class);
        }
      };

  private final ThreadMXBean threads;
  private final BlockedThreadsConfigurator collectorsSupplier;

  @Inject
  public BlockedThreadsCheck(
      ListeningExecutorService executor,
      HealthCheckConfig healthCheckConfig,
      HealthCheckMetrics.Factory healthCheckMetricsFactory,
      ThreadBeanProvider threadBeanProvider,
      BlockedThreadsConfigurator checksConfig) {
    super(executor, healthCheckConfig, BLOCKEDTHREADS, healthCheckMetricsFactory);
    this.threads = threadBeanProvider.get();
    this.collectorsSupplier = checksConfig;
  }

  @Override
  protected Result doCheck() throws Exception {
    List<Collector> collectors = collectorsSupplier.createCollectors();
    dumpAllThreads().forEach(info -> collectors.forEach(c -> c.collect(info)));

    // call check on all sub-checks so that metrics are populated
    collectors.forEach(Collector::check);

    // report unhealthy instance if any of sub-checks failed
    return collectors.stream()
        .map(Collector::result)
        .filter(r -> Result.FAILED == r)
        .findAny()
        .orElse(Result.PASSED);
  }

  private Stream<ThreadInfo> dumpAllThreads() {
    // getting all thread ids and translating it into thread infos is noticeably faster then call to
    // ThreadMXBean.dumpAllThreads as it doesn't calculate StackTrace. Note that some threads could
    // be already finished (between call to get all ids and translate them to ThreadInfo objects
    // hence they have to be filtered out).
    return Arrays.stream(threads.getThreadInfo(threads.getAllThreadIds(), 0))
        .filter(Objects::nonNull);
  }

  @VisibleForTesting
  public static class ThreadBeanProvider {
    public ThreadMXBean get() {
      return ManagementFactory.getThreadMXBean();
    }
  }

  static class Collector {
    protected final Integer threshold;

    protected int blocked;
    protected int total;
    protected Result result;

    Collector(Integer threshold) {
      this.threshold = threshold;
    }

    void collect(ThreadInfo info) {
      total += 1;
      if (Thread.State.BLOCKED == info.getThreadState()) {
        blocked += 1;
      }
    }

    void check() {
      result = blocked * 100 <= threshold * total ? Result.PASSED : Result.FAILED;
    }

    Result result() {
      return result;
    }
  }

  interface CollectorProvider<T extends Collector> extends Provider<T> {}
}
