/*
 * 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;

import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.util.Getter;
import com.intellij.openapi.vcs.impl.VcsRootIterator;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.Nullable;
import org.tmatesoft.svn.core.internal.util.SVNEncodingUtil;
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
import org.tmatesoft.svn.core.wc.SVNInfo;

import java.util.*;

public class ForNestedRootChecker {
  static class DirInfo {
    private final VirtualFile myFile;
    private final String myUrl;

    DirInfo(final VirtualFile file, final String url) {
      myFile = file;
      myUrl = url;
    }

    public VirtualFile getFile() {
      return myFile;
    }

    public String getUrl() {
      return myUrl;
    }
  }

  private static class UrlConstructor {
    final SvnVcs myVcs;

    private UrlConstructor(final SvnVcs vcs) {
      myVcs = vcs;
    }

    @Nullable
    public Real createReal(final VirtualFile file, final VirtualFile vcsRoot) {
      final SVNInfo info = myVcs.getInfo(file);
      if (info == null || info.getRepositoryRootURL() == null || info.getURL() == null) {
        return null;
      }
      return new Real(file, info, vcsRoot);
    }

    public Node createReplaceable(final VirtualFile file) {
      return new Node(file, null);
    }

    public Node createSupposed(final Real parent, final VirtualFile child) {
      return new Node(child, getForChild(parent.getUrl(), child.getName()));
    }

    public boolean replaceWithReal(final Real real, final Node supposed) {
      return supposed.getUrl() == null || ((supposed.getUrl() != null) && (! supposed.getUrl().equals(real.getUrl())));
    }

    @Nullable
    private String getSupposedUrl(final String parentUrl, final List<String> subpath) {
      if (parentUrl == null) return null;
      final StringBuilder sb = new StringBuilder();
      for (String s : subpath) {
        sb.append(s).append('/');
      }
      if (sb.length() > 0) {
        sb.deleteCharAt(sb.length() - 1);
      }
      return SVNPathUtil.append(parentUrl, sb.toString());
    }

    public String getForChild(final String parentUrl, final String childName) {
      return parentUrl == null ? null : SVNPathUtil.append(parentUrl, SVNEncodingUtil.uriEncode(childName));
    }
  }

  public static<T extends RootUrlPair> void filterOutSuperfluousChildren(final SvnVcs vcs, final List<T> list,
                                                                               final List<T> result) {
    final UrlConstructor constructor = new UrlConstructor(vcs);

    Collections.sort(list, new Comparator<RootUrlPair>() {
      public int compare(final RootUrlPair o1, final RootUrlPair o2) {
        return o1.getVirtualFile().getPath().compareTo(o2.getVirtualFile().getPath());
      }
    });

    for (int i = 0; i < list.size(); i++) {
      final T child = list.get(i);
      boolean add = true;
      for (T parent : result) {
        if (parent.getVirtualFile().getPath().equals(child.getVirtualFile().getPath())) {
          add = false;
          break;
        }
        final List<String> subpath = subpathIfAncestor(parent.getVirtualFile(), child.getVirtualFile());
        if (subpath != null) {
          // get child's supposed and real urls
          final String supposed = constructor.getSupposedUrl(parent.getUrl(), subpath);
          if (supposed.equals(child.getUrl())) {
            add = false;
            break;
          }
        }
      }
      if (add) {
        result.add(child);
      }
    }
  }

  @Nullable
  private static List<String> subpathIfAncestor(final VirtualFile parent, final VirtualFile child) {
    if (! VfsUtil.isAncestor(parent, child, true)) return null;

    final List<String> result = new ArrayList<String>();
    VirtualFile tmp = child;
    final String parentPath = parent.getPath();
    while ((tmp != null) && (! tmp.getPath().equals(parentPath))) {
      result.add(tmp.getName());
      tmp = tmp.getParent();
    }
    Collections.reverse(result);
    return result;
  }

  /*public static List<Real> getAllNestedWorkingCopies(final VirtualFile[] roots, final SvnVcs vcs, final boolean goIntoNested) {
    if (goIntoNested) {
      FilterDescendantVirtualFiles.filter(Arrays.asList(roots));
    }

    final VcsRootIterator rootIterator = new VcsRootIterator(vcs.getProject(), vcs);
    final List<Real> result = new ArrayList<Real>();
    for (VirtualFile root : roots) {
      result.addAll(getForOne(root, vcs, goIntoNested, rootIterator));
    }

    if (! goIntoNested) {
      final List<Real> filtered = new ArrayList<Real>(result.size());
      filterOutSuperfluousChildren(vcs, result, filtered);
      return filtered;
    }

    return result;
  }*/

  public static List<Real> getAllNestedWorkingCopies(final VirtualFile root, final SvnVcs vcs, final boolean goIntoNested, final Getter<Boolean> cancelledGetter) {
    final VcsRootIterator rootIterator = new VcsRootIterator(vcs.getProject(), vcs);
    return getForOne(root, vcs, goIntoNested, rootIterator, cancelledGetter);
  }

  private static List<Real> getForOne(final VirtualFile root, final SvnVcs vcs, final boolean goIntoNested,
                                      final VcsRootIterator rootIterator, final Getter<Boolean> cancelledGetter) {
    final UrlConstructor constructor = new UrlConstructor(vcs);
    final LinkedList<Node> queue = new LinkedList<Node>();
    final LinkedList<Real> result = new LinkedList<Real>();

    queue.add(constructor.createReplaceable(root));
    while (! queue.isEmpty()) {
      final Node node = queue.removeFirst();
      if (Boolean.TRUE.equals(cancelledGetter.get())) throw new ProcessCanceledException();

      // check self
      final Real real = constructor.createReal(node.getFile(), root);
      if (real != null) {
        if (constructor.replaceWithReal(real, node)) {
          result.add(real);
          if (! goIntoNested) continue;
        }
      }

      // for next step
      final VirtualFile file = node.getFile();
      if (file.isDirectory() && (! SvnUtil.isAdminDirectory(file))) {
        for (VirtualFile child : file.getChildren()) {
          if (Boolean.TRUE.equals(cancelledGetter.get())) throw new ProcessCanceledException();
          if (rootIterator.acceptFolderUnderVcs(root, child)) {
            if (real == null) {
              queue.add(constructor.createReplaceable(child));
            } else {
              queue.add(constructor.createSupposed(real, child));
            }
          }
        }
      }
    }
    return result;
  }
}
