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

import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.RootUrlInfo;
import org.jetbrains.idea.svn.SvnFileUrlMapping;
import org.jetbrains.idea.svn.SvnUtil;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.commandLine.SvnBindException;
import org.jetbrains.idea.svn.info.Info;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.internal.util.SVNURLUtil;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc2.SvnTarget;

import java.util.Map;

public class LatestExistentSearcher {

  private static final Logger LOG = Logger.getInstance(LatestExistentSearcher.class);

  private long myStartNumber;
  private boolean myStartExistsKnown;
  @NotNull private final SVNURL myUrl;
  @NotNull private final SVNURL myRepositoryUrl;
  @NotNull private final String myRelativeUrl;
  private final SvnVcs myVcs;
  private long myEndNumber;

  public LatestExistentSearcher(final SvnVcs vcs, @NotNull SVNURL url, @NotNull SVNURL repositoryUrl) {
    this(0, -1, false, vcs, url, repositoryUrl);
  }

  public LatestExistentSearcher(final long startNumber,
                                final long endNumber,
                                final boolean startExistsKnown,
                                final SvnVcs vcs,
                                @NotNull SVNURL url,
                                @NotNull SVNURL repositoryUrl) {
    myStartNumber = startNumber;
    myEndNumber = endNumber;
    myStartExistsKnown = startExistsKnown;
    myVcs = vcs;
    myUrl = url;
    myRepositoryUrl = repositoryUrl;
    // TODO: Make utility method that compare relative urls checking all possible cases when start/end slash exists or not.
    myRelativeUrl = SvnUtil.ensureStartSlash(SVNURLUtil.getRelativeURL(myRepositoryUrl, myUrl, true));
  }

  public long getDeletionRevision() {
    if (! detectStartRevision()) return -1;

    final Ref<Long> latest = new Ref<Long>(myStartNumber);
    try {
      if (myEndNumber == -1) {
        myEndNumber = getLatestRevision();
      }

      final SVNURL existingParent = getExistingParent(myUrl);
      if (existingParent == null) {
        return myStartNumber;
      }

      final SVNRevision startRevision = SVNRevision.create(myStartNumber);
      SvnTarget target = SvnTarget.fromURL(existingParent, startRevision);
      myVcs.getFactory(target).createHistoryClient().doLog(target, startRevision, SVNRevision.HEAD, false, true, false, 0, null,
                                                           createHandler(latest));
    }
    catch (VcsException e) {
      LOG.info(e);
    }

    return latest.get().longValue();
  }

  @NotNull
  private LogEntryConsumer createHandler(@NotNull final Ref<Long> latest) {
    return new LogEntryConsumer() {
      @Override
      public void consume(final LogEntry logEntry) throws SVNException {
        final Map changedPaths = logEntry.getChangedPaths();
        for (Object o : changedPaths.values()) {
          final LogEntryPath path = (LogEntryPath)o;
          if ((path.getType() == 'D') && (myRelativeUrl.equals(path.getPath()))) {
            latest.set(logEntry.getRevision());
            throw new SVNException(SVNErrorMessage.UNKNOWN_ERROR_MESSAGE);
          }
        }
      }
    };
  }

  public long getLatestExistent() {
    if (! detectStartRevision()) return myStartNumber;

    long latestOk = myStartNumber;
    try {
      if (myEndNumber == -1) {
        myEndNumber = getLatestRevision();
      }
      // TODO: At least binary search could be applied here for optimization
      for (long i = myStartNumber + 1; i < myEndNumber; i++) {
        if (existsInRevision(myUrl, i)) {
          latestOk = i;
        }
      }
    }
    catch (SvnBindException e) {
      LOG.info(e);
    }

    return latestOk;
  }

  private boolean detectStartRevision() {
    if (! myStartExistsKnown) {
      final SvnFileUrlMapping mapping = myVcs.getSvnFileUrlMapping();
      final RootUrlInfo rootUrlInfo = mapping.getWcRootForUrl(myUrl.toString());
      if (rootUrlInfo == null) return true;
      final VirtualFile vf = rootUrlInfo.getVirtualFile();
      final Info info = myVcs.getInfo(vf);
      if ((info == null) || (info.getRevision() == null)) {
        return false;
      }
      myStartNumber = info.getRevision().getNumber();
      myStartExistsKnown = true;
    }
    return true;
  }

  @Nullable
  private SVNURL getExistingParent(SVNURL url) throws SvnBindException {
    while (url != null && !url.equals(myRepositoryUrl) && !existsInRevision(url, myEndNumber)) {
      url = SvnUtil.removePathTail(url);
    }

    return url;
  }

  private boolean existsInRevision(@NotNull SVNURL url, long revisionNumber) throws SvnBindException {
    SVNRevision revision = SVNRevision.create(revisionNumber);
    Info info = null;

    try {
      info = myVcs.getInfo(url, revision, revision);
    }
    catch (SvnBindException e) {
      // throw error if not "does not exist" error code
      if (!e.contains(SVNErrorCode.RA_ILLEGAL_URL)) {
        throw e;
      }
    }

    return info != null;
  }

  private long getLatestRevision() throws SvnBindException {
    return SvnUtil.getHeadRevision(myVcs, myRepositoryUrl).getNumber();
  }
}
