// 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.server.plugins;

import com.google.gerrit.common.TimeUtil;
import com.google.gerrit.server.git.WorkQueue;
import com.google.inject.Inject;
import com.google.inject.Singleton;

import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

@Singleton
class PluginCleanerTask implements Runnable {
  private final WorkQueue workQueue;
  private final PluginLoader loader;
  private volatile int pending;
  private Future<?> self;
  private int attempts;
  private long start;

  @Inject
  PluginCleanerTask(WorkQueue workQueue, PluginLoader loader) {
    this.workQueue = workQueue;
    this.loader = loader;
  }

  @Override
  public void run() {
    try {
      for (int t = 0; t < 2 * (attempts + 1); t++) {
        System.gc();
        Thread.sleep(50);
      }
    } catch (InterruptedException e) {
    }

    int left = loader.processPendingCleanups();
    synchronized (this) {
      pending = left;
      self = null;

      if (0 < left) {
        long waiting = TimeUtil.nowMs() - start;
        PluginLoader.log.warn(String.format(
            "%d plugins still waiting to be reclaimed after %d minutes",
            pending,
            TimeUnit.MILLISECONDS.toMinutes(waiting)));
        attempts = Math.min(attempts + 1, 15);
        ensureScheduled();
      } else {
        attempts = 0;
      }
    }
  }

  @Override
  public String toString() {
    int p = pending;
    if (0 < p) {
      return String.format("Plugin Cleaner (waiting for %d plugins)", p);
    }
    return "Plugin Cleaner";
  }

  synchronized void clean(int expect) {
    if (self == null && pending == 0) {
      start = TimeUtil.nowMs();
    }
    pending = expect;
    ensureScheduled();
  }

  private void ensureScheduled() {
    if (self == null && 0 < pending) {
      if (attempts == 1) {
        self = workQueue.getDefaultQueue().schedule(
            this,
            30,
            TimeUnit.SECONDS);
      } else {
        self = workQueue.getDefaultQueue().schedule(
            this,
            attempts + 1,
            TimeUnit.MINUTES);
      }
    }
  }
}
