// 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.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 = System.currentTimeMillis() - 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 = System.currentTimeMillis();
    }
    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);
      }
    }
  }
}
