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

import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.ObjectsConvertor;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.Convertor;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnUtil;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.integrate.SvnBranchItem;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
import org.tmatesoft.svn.core.internal.util.SVNURLUtil;
import org.tmatesoft.svn.core.wc.SVNInfo;

import java.io.File;
import java.util.*;

public class SvnBranchConfigurationNew {
  private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew");
  private String myTrunkUrl;
  // need public for serialization
  public Map<String, InfoStorage<List<SvnBranchItem>>> myBranchMap;
  private boolean myUserinfoInUrl;

  public SvnBranchConfigurationNew() {
    myTrunkUrl = "";
    myBranchMap = new HashMap<String, InfoStorage<List<SvnBranchItem>>>();
  }

  public boolean isUserinfoInUrl() {
    return myUserinfoInUrl;
  }

  public void setUserinfoInUrl(final boolean userinfoInUrl) {
    myUserinfoInUrl = userinfoInUrl;
  }

  public void setTrunkUrl(final String trunkUrl) {
    myTrunkUrl = trunkUrl;
  }

  public String getTrunkUrl() {
    return myTrunkUrl;
  }

  public List<String> getBranchUrls() {
    final ArrayList<String> result = new ArrayList<String>(myBranchMap.keySet());
    final List<String> cutList = ObjectsConvertor.convert(result, new Convertor<String, String>() {
      @Override
      public String convert(String s) {
        return cutEndSlash(s);
      }
    });
    Collections.sort(cutList);
    return cutList;
  }

  public void addBranches(String branchParentName, final InfoStorage<List<SvnBranchItem>> items) {
    branchParentName = ensureEndSlash(branchParentName);
    InfoStorage<List<SvnBranchItem>> current = myBranchMap.get(branchParentName);
    if (current != null) {
      LOG.info("Branches list not added for : '" + branchParentName + "; this branch parent URL is already present.");
      return;
    }
    myBranchMap.put(branchParentName, items);
  }

  public static String ensureEndSlash(String name) {
    return name.trim().endsWith("/") ? name : name + "/";
  }
  
  private static String cutEndSlash(String name) {
    return name.endsWith("/") && name.length() > 0 ? name.substring(0, name.length() - 1) : name;
  }

  public void updateBranch(String branchParentName, final InfoStorage<List<SvnBranchItem>> items) {
    branchParentName = ensureEndSlash(branchParentName);
    final InfoStorage<List<SvnBranchItem>> current = myBranchMap.get(branchParentName);
    if (current == null) {
      LOG.info("Branches list not updated for : '" + branchParentName + "; since config has changed.");
      return;
    }
    current.accept(items, null);
  }

  public Map<String, InfoStorage<List<SvnBranchItem>>> getBranchMap() {
    return myBranchMap;
  }

  public List<SvnBranchItem> getBranches(String url) {
    url = ensureEndSlash(url);
    return myBranchMap.get(url).getValue();
  }

  public SvnBranchConfigurationNew copy() {
    SvnBranchConfigurationNew result = new SvnBranchConfigurationNew();
    result.myUserinfoInUrl = myUserinfoInUrl;
    result.myTrunkUrl = myTrunkUrl;
    result.myBranchMap = new HashMap<String, InfoStorage<List<SvnBranchItem>>>();
    for (Map.Entry<String, InfoStorage<List<SvnBranchItem>>> entry : myBranchMap.entrySet()) {
      final InfoStorage<List<SvnBranchItem>> infoStorage = entry.getValue();
      result.myBranchMap.put(entry.getKey(), new InfoStorage<List<SvnBranchItem>>(
        new ArrayList<SvnBranchItem>(infoStorage.getValue()), infoStorage.getInfoReliability()));
    }
    return result;
  }

  @Nullable
  public String getBaseUrl(String url) {
    if (myTrunkUrl != null) {
      if (SVNPathUtil.isAncestor(myTrunkUrl, url)) {
        return cutEndSlash(myTrunkUrl);
      }
    }
    for(String branchUrl: myBranchMap.keySet()) {
      if (SVNPathUtil.isAncestor(branchUrl, url)) {
        String relativePath = SVNPathUtil.getRelativePath(branchUrl, url);
        int secondSlash = relativePath.indexOf("/");
        return cutEndSlash(branchUrl + (secondSlash == -1 ? relativePath : relativePath.substring(0, secondSlash)));
      }
    }
    return null;
  }

  @Nullable
  public String getBaseName(String url) {
    String baseUrl = getBaseUrl(url);
    if (baseUrl == null) {
      return null;
    }
    int lastSlash = baseUrl.lastIndexOf("/");
    return lastSlash == -1 ? baseUrl : baseUrl.substring(lastSlash + 1);
  }

  @Nullable
  public String getRelativeUrl(String url) {
    String baseUrl = getBaseUrl(url);
    return baseUrl == null ? null : url.substring(baseUrl.length());
  }

  @Nullable
  public SVNURL getWorkingBranch(final SVNURL someUrl) throws SVNException {
    String baseUrl = getBaseUrl(someUrl.toString());
    return baseUrl == null ? null : SVNURL.parseURIEncoded(baseUrl);
  }

  // todo not checked
  // todo +-
  @Nullable
  public String getGroupToLoadToReachUrl(final SVNURL url) throws SVNException {
    final BranchSearcher branchSearcher = new BranchSearcher(url);
    for (String group : myBranchMap.keySet()) {
      if (branchSearcher.accept(group)) {
        return group;
      }
    }
    return null;
  }

  private void iterateUrls(final UrlListener listener) throws SVNException {
    if (listener.accept(myTrunkUrl)) {
      return;
    }

    for (String branchUrl : myBranchMap.keySet()) {
      // use more exact comparison first (paths longer)
      final List<SvnBranchItem> children = myBranchMap.get(branchUrl).getValue();
      for (SvnBranchItem child : children) {
        if (listener.accept(child.getUrl())) {
          return;
        }
      }

      /*if (listener.accept(branchUrl)) {
        return;
      }*/
    }
  }

  // to retrieve mappings between existing in the project working copies and their URLs
  @Nullable
  public Map<String,String> getUrl2FileMappings(final Project project, final VirtualFile root) {
    try {
      final BranchRootSearcher searcher = new BranchRootSearcher(SvnVcs.getInstance(project), root);
      iterateUrls(searcher);
      return searcher.getBranchesUnder();
    } catch (SVNException e) {
      return null;
    }
  }

  public void removeBranch(String url) {
    url = ensureEndSlash(url);
    myBranchMap.remove(url);
  }

  private static class BranchRootSearcher implements UrlListener {
    private final VirtualFile myRoot;
    private final SVNURL myRootUrl;
    // url path to file path
    private final Map<String, String> myBranchesUnder;

    private BranchRootSearcher(final SvnVcs vcs, final VirtualFile root) throws SVNException {
      myRoot = root;
      myBranchesUnder = new HashMap<String, String>();
      final SVNInfo info = vcs.getInfo(myRoot.getPath());
      myRootUrl = info != null ? info.getURL() : null;
    }

    public boolean accept(final String url) throws SVNException {
      if (myRootUrl != null) {
        final File baseDir = new File(myRoot.getPath());
        final String baseUrl = myRootUrl.getPath();

        final SVNURL branchUrl = SVNURL.parseURIEncoded(url);
        if (myRootUrl.equals(SVNURLUtil.getCommonURLAncestor(myRootUrl, branchUrl))) {
          final File file = SvnUtil.fileFromUrl(baseDir, baseUrl, branchUrl.getPath());
          myBranchesUnder.put(url, file.getAbsolutePath());
        }
      }
      return false; // iterate everything
    }

    public Map<String, String> getBranchesUnder() {
      return myBranchesUnder;
    }
  }

  private interface UrlListener {
    boolean accept(final String url) throws SVNException;
  }

  // todo not checked
  private static class BranchSearcher implements UrlListener {
    private final SVNURL mySomeUrl;
    private SVNURL myResult;

    private BranchSearcher(final SVNURL someUrl) {
      mySomeUrl = someUrl;
    }

    public boolean accept(final String url) throws SVNException {
      myResult = urlIsParent(url, mySomeUrl);
      return myResult != null;
    }

    public SVNURL getResult() {
      return myResult;
    }
  }

  @Nullable
  private static SVNURL urlIsParent(final String parentCandidate, final SVNURL child) throws SVNException {
    final SVNURL parentUrl = SVNURL.parseURIEncoded(parentCandidate);
    if(parentUrl.equals(SVNURLUtil.getCommonURLAncestor(parentUrl, child))) {
      return parentUrl;
    }
    return null;
  }
}
