/*
 * Copyright 2000-2012 JetBrains s.r.o.
 *
 * 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 org.jetbrains.idea.svn.svnkit.lowLevel;

import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.util.containers.hash.HashSet;
import org.tmatesoft.svn.core.SVNErrorCode;
import org.tmatesoft.svn.core.SVNErrorMessage;
import org.tmatesoft.svn.core.SVNException;

import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

/**
 * Created with IntelliJ IDEA.
 * User: Irina.Chernushina
 * Date: 7/31/12
 * Time: 6:19 PM
 */
public class ApplicationLevelNumberConnectionsGuardImpl implements Disposable, ApplicationLevelNumberConnectionsGuard {
  public static final int DELAY = 20000;

  private final Object myLock;
  private final Set<CachingSvnRepositoryPool> mySet;
  private int myCurrentlyActiveConnections;
  private int myCurrentlyOpenedConnections;
  private boolean myDisposed;

  private int myInstanceCount;  // refreshable instances
  private final ScheduledExecutorService myService;
  private ScheduledFuture<?> myFuture;
  private final Runnable myRecheck;
  private int myDelay;
  private int myCurrentlyOpenedCount;

  public ApplicationLevelNumberConnectionsGuardImpl() {
    myDelay = DELAY;
    mySet = new HashSet<CachingSvnRepositoryPool>();
    myService = Executors.newSingleThreadScheduledExecutor();
    myLock = new Object();
    myDisposed = false;
    myRecheck = new Runnable() {
      @Override
      public void run() {
        HashSet<CachingSvnRepositoryPool> pools = new HashSet<CachingSvnRepositoryPool>();
        synchronized (myLock) {
          pools.addAll(mySet);
        }
        for (CachingSvnRepositoryPool pool : pools) {
          pool.check();
        }
      }
    };
    myCurrentlyActiveConnections = 0;
    myCurrentlyOpenedConnections = 0;
  }

  public void setDelay(int delay) {
    assert ApplicationManager.getApplication().isUnitTestMode();
    myDelay = delay;
    myFuture.cancel(true);
    myFuture = myService.scheduleWithFixedDelay(myRecheck, myDelay, myDelay, TimeUnit.MILLISECONDS);
  }

  public int getCurrentlyActiveConnections() {
    synchronized (myLock) {
      assert ApplicationManager.getApplication().isUnitTestMode();
      return myCurrentlyActiveConnections;
    }
  }

  public int getInstanceCount() {
    assert ApplicationManager.getApplication().isUnitTestMode();
    return myInstanceCount;
  }

  public void addRepositoryPool(final CachingSvnRepositoryPool pool) {
    synchronized (myLock) {
      mySet.add(pool);
      ++ myInstanceCount;
      if (myFuture == null) {
        myFuture = myService.scheduleWithFixedDelay(myRecheck, myDelay, myDelay, TimeUnit.MILLISECONDS);
      }
    }
  }

  public void removeRepositoryPool(final CachingSvnRepositoryPool pool) {
    synchronized (myLock) {
      mySet.remove(pool);
      -- myInstanceCount;
      if (myInstanceCount == 0) {
        myFuture.cancel(true);
        myFuture = null;
      }
    }
  }

  @Override
  public void connectionCreated() {
    synchronized (myLock) {
      ++ myCurrentlyOpenedConnections;
    }
  }

  @Override
  public void connectionDestroyed(int number) {
    synchronized (myLock) {
      myCurrentlyOpenedConnections -= number;
    }
  }

  public void connectionOpened() {
    synchronized (myLock) {
      ++ myCurrentlyActiveConnections;
    }
  }

  public void connectionClosed() {
    synchronized (myLock) {
      -- myCurrentlyActiveConnections;
      myLock.notifyAll();
    }
  }

  @Override
  public void waitForTotalNumberOfConnectionsOk() throws SVNException {
    synchronized (myLock) {
      if (myCurrentlyActiveConnections >= CachingSvnRepositoryPool.ourMaxTotal) {
        waitForFreeConnections();
      }
    }
    // maybe too many opened? reduce request
    final Set<CachingSvnRepositoryPool> copy = new HashSet<CachingSvnRepositoryPool>();
    synchronized (myLock) {
      if (myCurrentlyOpenedConnections >= CachingSvnRepositoryPool.ourMaxTotal) {
        copy.addAll(mySet);
      }
    }
    for (CachingSvnRepositoryPool pool : copy) {
      pool.closeInactive();
    }
    synchronized (myLock) {
      waitForFreeConnections();
    }
  }

  private void waitForFreeConnections() throws SVNException {
    synchronized (myLock) {
      while (myCurrentlyActiveConnections >= CachingSvnRepositoryPool.ourMaxTotal && ! myDisposed) {
        try {
          myLock.wait(500);
        }
        catch (InterruptedException e) {
          //
        }
        ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
        if (indicator != null && indicator.isCanceled()) {
          throw new SVNException(SVNErrorMessage.create(SVNErrorCode.CANCELLED));
        }
      }
    }
  }

  @Override
  public boolean shouldKeepConnectionLocally() {
    synchronized (myLock) {
      if (myCurrentlyActiveConnections > CachingSvnRepositoryPool.ourMaxTotal ||
          myCurrentlyOpenedConnections > CachingSvnRepositoryPool.ourMaxTotal) return false;
    }
    return true;
  }

  @Override
  public void dispose() {
    synchronized (myLock) {
      myDisposed = true;
      myLock.notifyAll();
    }
  }

  public int getCurrentlyOpenedCount() {
    synchronized (myLock) {
      return myCurrentlyOpenedCount;
    }
  }
}
