/*
 * Copyright 2000-2009 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.dialogs;

import com.intellij.CommonBundle;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.util.NotNullFunction;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.FilteringIterator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.browse.DirectoryEntry;
import org.jetbrains.idea.svn.dialogs.browserCache.Expander;
import org.jetbrains.idea.svn.dialogs.browserCache.NodeLoadState;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;

import javax.swing.tree.TreeNode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;

public class RepositoryTreeNode implements TreeNode, Disposable {

  private TreeNode myParentNode;
  @NotNull private final List<TreeNode> myChildren;
  private final RepositoryTreeModel myModel;
  private final SVNURL myURL;
  private final Object myUserObject;

  @NotNull private final NodeLoadState myLoadState;
  private NodeLoadState myChildrenLoadState;

  public RepositoryTreeNode(RepositoryTreeModel model, TreeNode parentNode,
                            @NotNull SVNURL url, Object userObject, @NotNull NodeLoadState state) {
    myParentNode = parentNode;

    myURL = url;
    myModel = model;
    myUserObject = userObject;

    myLoadState = state;
    myChildren = ContainerUtil.newArrayList();
    myChildrenLoadState = NodeLoadState.EMPTY;
  }

  public RepositoryTreeNode(RepositoryTreeModel model, TreeNode parentNode, @NotNull SVNURL url, Object userObject) {
    // created outside: only roots
    this(model, parentNode, url, userObject, NodeLoadState.REFRESHED);
  }

  public Object getUserObject() {
    return myUserObject;
  }

  public int getChildCount() {
    return getChildren().size();
  }

  public Enumeration children() {
    return Collections.enumeration(getChildren());
  }

  public TreeNode getChildAt(int childIndex) {
    return (TreeNode) getChildren().get(childIndex);
  }

  public int getIndex(TreeNode node) {
    return getChildren().indexOf(node);
  }

  public boolean getAllowsChildren() {
    return !isLeaf();
  }

  public boolean isLeaf() {
    return myUserObject instanceof DirectoryEntry && ((DirectoryEntry)myUserObject).isFile();
  }

  public TreeNode getParent() {
    return myParentNode;
  }

  public void reload(final boolean removeCurrentChildren) {
    // todo lazyLoading as explicit: keeping...
    reload(removeCurrentChildren ? myModel.getSelectionKeepingExpander() : myModel.getLazyLoadingExpander(), removeCurrentChildren);
  }

  @Nullable
  public TreeNode getNextChildByKey(final String key, final boolean isFolder) {
    final ByKeySelectedSearcher searcher = (isFolder) ? new FolderByKeySelectedSearcher(key, myChildren) :
                                                 new FileByKeySelectedSearcher(key, myChildren);
    return searcher.getNextSelectedByKey();
  }

  public String toString() {
    if (myParentNode instanceof RepositoryTreeRootNode) {
      return myURL.toString();
    }
    return SVNPathUtil.tail(myURL.getPath());
  }

  public void reload(@NotNull Expander expander, boolean removeCurrentChildren) {
    ApplicationManager.getApplication().assertIsDispatchThread();

    if (removeCurrentChildren || NodeLoadState.EMPTY.equals(myChildrenLoadState)) {
      initChildren();
    }
    
    myModel.getCacheLoader().load(this, expander);
  }

  private void initChildren() {
    myChildren.clear();
    myChildren.add(new SimpleTextNode(CommonBundle.getLoadingTreeNodeText()));
    myChildrenLoadState = NodeLoadState.LOADING;
  }

  private List getChildren() {
    ApplicationManager.getApplication().assertIsDispatchThread();

    if (NodeLoadState.EMPTY.equals(myChildrenLoadState)) {
      initChildren();
      myModel.getCacheLoader().load(this, myModel.getLazyLoadingExpander());
    }
    return myChildren;
  }

  public SVNURL getURL() {
    return myURL;
  }

  @Nullable
  public DirectoryEntry getSVNDirEntry() {
    return myUserObject instanceof DirectoryEntry ? (DirectoryEntry)myUserObject : null;
  }

  public void dispose() {
  }

  public TreeNode[] getSelfPath() {
    return myModel.getPathToRoot(this);
  }

  public boolean isRepositoryRoot() {
    return ! (myUserObject instanceof DirectoryEntry);
  }

  @NotNull
  public List<TreeNode> getAllAlreadyLoadedChildren() {
    return ContainerUtil.newArrayList(myChildren);
  }

  @NotNull
  public List<RepositoryTreeNode> getAlreadyLoadedChildren() {
    return ContainerUtil.collect(myChildren.iterator(), FilteringIterator.instanceOf(RepositoryTreeNode.class));
  }

  public boolean isDisposed() {
    return myModel.isDisposed();
  }

  public void setChildren(@NotNull List<DirectoryEntry> children, @NotNull NodeLoadState state) {
    final List<TreeNode> nodes = new ArrayList<TreeNode>();
    for (final DirectoryEntry entry : children) {
      if (!myModel.isShowFiles() && !entry.isDirectory()) {
        continue;
      }
      nodes.add(new RepositoryTreeNode(myModel, this, entry.getUrl(), entry, state));
    }

    myChildrenLoadState = state;
    myChildren.clear();
    myChildren.addAll(nodes);

    myModel.reload(this);
  }

  public void setParentNode(final TreeNode parentNode) {
    myParentNode = parentNode;
  }

  public void setAlienChildren(final List<TreeNode> children, final NodeLoadState oldState) {
    myChildren.clear();

    for (TreeNode child : children) {
      if (child instanceof RepositoryTreeNode) {
        ((RepositoryTreeNode) child).setParentNode(this);
        myChildren.add(child);
        myChildrenLoadState = oldState;
      }
      else if (child instanceof SimpleTextNode) {
        SimpleTextNode node = (SimpleTextNode)child;
        myChildren.add(new SimpleTextNode(node.getText(), node.isError()));
        myChildrenLoadState = oldState;
      }
    }

    myModel.reload(this);
  }

  public void setErrorNode(@NotNull String text) {
    myChildren.clear();
    myChildren.add(new SimpleTextNode(text, true));
    myChildrenLoadState = NodeLoadState.ERROR;
    myModel.reload(this);
  }

  public SvnVcs getVcs() {
    return myModel.getVCS();
  }

  public boolean isCached() {
    return NodeLoadState.CACHED.equals(myLoadState);
  }

  @Nullable
  public RepositoryTreeNode getNodeWithSamePathUnderModelRoot() {
    return myModel.findByUrl(this);
  }

  public NodeLoadState getChildrenLoadState() {
    return myChildrenLoadState;
  }

  public void doOnSubtree(@NotNull NotNullFunction<RepositoryTreeNode, Object> function) {
    new SubTreeWalker(this, function).execute();
  }

  private static class SubTreeWalker {

    @NotNull private final RepositoryTreeNode myNode;
    @NotNull private final NotNullFunction<RepositoryTreeNode, Object> myFunction;

    private SubTreeWalker(@NotNull RepositoryTreeNode node, @NotNull NotNullFunction<RepositoryTreeNode, Object> function) {
      myNode = node;
      myFunction = function;
    }

    public void execute() {
      executeImpl(myNode);
    }

    private void executeImpl(final RepositoryTreeNode node) {
      myFunction.fun(node);
      for (RepositoryTreeNode child : node.getAlreadyLoadedChildren()) {
        myFunction.fun(child);
      }
    }
  }
}
