/*
 * Copyright 2000-2014 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 com.intellij.openapi.vcs;

import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.SomeQueue;
import com.intellij.openapi.util.Couple;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Consumer;
import com.intellij.util.Function;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * For exactly same refresh requests buffering:
 * <p/>
 * - refresh requests can be merged into one, but general principle is that each request should be reliably followed by refresh action
 * - at the moment only one refresh action is being done
 * - if request had been submitted while refresh action was in progress, new refresh action is initiated right after first refresh action finishes
 */
@SomeQueue
public class RequestsMerger {
  private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.RequestsMerger");

  private final MyWorker myWorker;

  private final Object myLock = new Object();

  private MyState myState;
  private final Consumer<Runnable> myAlarm;

  private final List<Runnable> myWaitingStartListeners = new ArrayList<Runnable>();
  private final List<Runnable> myWaitingFinishListeners = new ArrayList<Runnable>();

  public RequestsMerger(final Runnable runnable, final Consumer<Runnable> alarm) {
    myAlarm = alarm;
    myWorker = new MyWorker(runnable);

    myState = MyState.empty;
  }

  public void request() {
    LOG.debug("ext: request");
    doAction(MyAction.request);
  }

  public void waitRefresh(final Runnable runnable) {
    LOG.debug("ext: wait refresh");
    synchronized (myLock) {
      myWaitingStartListeners.add(runnable);
    }
    request();
  }

  private class MyWorker implements Runnable {
    private volatile boolean myInitialized;
    private final Runnable myRunnable;

    private MyWorker(Runnable runnable) {
      myRunnable = runnable;
    }

    @Override
    public void run() {
      LOG.debug("worker: started refresh");
      try {
        doAction(MyAction.start);
        myRunnable.run();
        myInitialized = true;
      }
      finally {
        doAction(MyAction.finish);
      }
    }

    public boolean isInitialized() {
      return myInitialized;
    }
  }

  private void doAction(final MyAction action) {
    LOG.debug("doAction: START " + action.name());
    final MyExitAction[] exitActions;
    List<Runnable> toBeCalled = null;
    synchronized (myLock) {
      final MyState oldState = myState;
      myState = myState.transition(action);
      if (oldState.equals(myState)) return;
      exitActions = MyTransitionAction.getExit(oldState, myState);

      LOG.debug("doAction: oldState: " + oldState.name() + ", newState: " + myState.name());

      if (LOG.isDebugEnabled() && exitActions != null) {
        final String debugExitActions = StringUtil.join(exitActions, new Function<MyExitAction, String>() {
          @Override
          public String fun(MyExitAction exitAction) {
            return exitAction.name();
          }
        }, " ");
        LOG.debug("exit actions: " + debugExitActions);
      }
      if (exitActions != null) {
        for (MyExitAction exitAction : exitActions) {
          if (MyExitAction.markStart.equals(exitAction)) {
            myWaitingFinishListeners.addAll(myWaitingStartListeners);
            myWaitingStartListeners.clear();
          }
          else if (MyExitAction.markEnd.equals(exitAction)) {
            toBeCalled = new ArrayList<Runnable>(myWaitingFinishListeners);
            myWaitingFinishListeners.clear();
          }
        }
      }
    }
    if (exitActions != null) {
      for (MyExitAction exitAction : exitActions) {
        if (MyExitAction.submitRequestToExecutor.equals(exitAction)) {
          myAlarm.consume(myWorker);
          //myAlarm.addRequest(myWorker, ourDelay);
          //ApplicationManager.getApplication().executeOnPooledThread(myWorker);
        }
      }
    }
    if (toBeCalled != null) {
      for (Runnable runnable : toBeCalled) {
        runnable.run();
      }
    }
    LOG.debug("doAction: END " + action.name());
  }

  private enum MyState {
    empty() {
      @Override
      @NotNull
      public MyState transition(MyAction action) {
        if (MyAction.request.equals(action)) {
          return MyState.requestSubmitted;
        }
        logWrongAction(this, action);
        return this;
      }
    },
    inProgress() {
      @Override
      @NotNull
      public MyState transition(MyAction action) {
        if (MyAction.finish.equals(action)) {
          return empty;
        }
        else if (MyAction.request.equals(action)) {
          return MyState.inProgressRequestSubmitted;
        }
        logWrongAction(this, action);
        return this;
      }
    },
    inProgressRequestSubmitted() {
      @Override
      @NotNull
      public MyState transition(MyAction action) {
        if (MyAction.finish.equals(action)) {
          return MyState.requestSubmitted;
        }
        if (MyAction.start.equals(action)) {
          logWrongAction(this, action);
        }
        return this;
      }
    },
    requestSubmitted() {
      @Override
      @NotNull
      public MyState transition(MyAction action) {
        if (MyAction.start.equals(action)) {
          return inProgress;
        }
        else if (MyAction.finish.equals(action)) {
          // to be able to be started by another request
          logWrongAction(this, action);
          return empty;
        }
        return this;
      }
    };

    // under lock
    @NotNull
    public abstract MyState transition(final MyAction action);

    private static void logWrongAction(final MyState state, final MyAction action) {
      LOG.info("Wrong action: state=" + state.name() + ", action=" + action.name());
    }
  }

  private static class MyTransitionAction {
    private static final Map<Couple<MyState>, MyExitAction[]> myMap = new HashMap<Couple<MyState>, MyExitAction[]>();

    static {
      add(MyState.empty, MyState.requestSubmitted, MyExitAction.submitRequestToExecutor);
      add(MyState.requestSubmitted, MyState.inProgress, MyExitAction.markStart);
      add(MyState.inProgress, MyState.empty, MyExitAction.markEnd);
      add(MyState.inProgressRequestSubmitted, MyState.requestSubmitted, MyExitAction.submitRequestToExecutor, MyExitAction.markEnd);

      //... and not real but to be safe:
      add(MyState.inProgressRequestSubmitted, MyState.empty, MyExitAction.markEnd);
      add(MyState.inProgress, MyState.requestSubmitted, MyExitAction.markEnd);
    }

    private static void add(final MyState from, final MyState to, final MyExitAction... action) {
      myMap.put(Couple.of(from, to), action);
    }

    @Nullable
    public static MyExitAction[] getExit(final MyState from, final MyState to) {
      return myMap.get(Couple.of(from, to));
    }
  }

  private enum MyExitAction {
    empty,
    submitRequestToExecutor,
    markStart,
    markEnd
  }

  private enum MyAction {
    request,
    start,
    finish
  }
}
