package org.jetbrains.idea.svn.upgrade;

import com.intellij.execution.process.ProcessOutputTypes;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.util.containers.Convertor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.WorkingCopyFormat;
import org.jetbrains.idea.svn.api.*;
import org.jetbrains.idea.svn.commandLine.CommandUtil;
import org.jetbrains.idea.svn.commandLine.LineCommandAdapter;
import org.jetbrains.idea.svn.commandLine.SvnCommandName;
import org.tmatesoft.svn.core.wc2.SvnTarget;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Konstantin Kolosovsky.
 */
public class CmdUpgradeClient extends BaseSvnClient implements UpgradeClient {

  private static final String STATUS = "\\s*(.+?)\\s*";
  private static final String PATH = "\\s*\'(.*?)\'\\s*";
  private static final Pattern CHANGED_PATH = Pattern.compile(STATUS + PATH);

  @Override
  public void upgrade(@NotNull File path, @NotNull WorkingCopyFormat format, @Nullable ProgressTracker handler) throws VcsException {
    validateFormat(format, getSupportedFormats());

    // fake event indicating upgrade start
    callHandler(handler, createEvent(path, EventAction.UPDATE_COMPLETED));

    List<String> parameters = new ArrayList<String>();

    CommandUtil.put(parameters, path);

    // TODO: Add general possibility to invoke "handler.checkCancelled" (process should be killed). But currently upgrade process is not
    // TODO: cancellable from UI - and this makes sense.
    // for 1.8 - no output
    // for 1.7 - output in format "Upgraded '<path>'"
    FileStatusResultParser parser = new FileStatusResultParser(CHANGED_PATH, handler, new UpgradeStatusConvertor());
    UpgradeLineCommandListener listener = new UpgradeLineCommandListener(parser);

    execute(myVcs, SvnTarget.fromFile(path), SvnCommandName.upgrade, parameters, listener);
    listener.throwIfException();
  }

  @Override
  public List<WorkingCopyFormat> getSupportedFormats() throws VcsException {
    List<WorkingCopyFormat> result = new ArrayList<WorkingCopyFormat>();

    result.add(WorkingCopyFormat.from(myFactory.createVersionClient().getVersion()));

    return result;
  }

  private static class UpgradeStatusConvertor implements Convertor<Matcher, ProgressEvent> {

    public ProgressEvent convert(@NotNull Matcher matcher) {
      String statusMessage = matcher.group(1);
      String path = matcher.group(2);

      return createEvent(new File(path), createAction(statusMessage));
    }

    @Nullable
    public static EventAction createAction(@NotNull String code) {
      EventAction result = null;

      if ("Upgraded".equals(code)) {
        result = EventAction.UPGRADED_PATH;
      }

      return result;
    }
  }

  private static class UpgradeLineCommandListener extends LineCommandAdapter {

    @NotNull private final FileStatusResultParser parser;
    @NotNull private final AtomicReference<VcsException> exception;

    private UpgradeLineCommandListener(@NotNull FileStatusResultParser parser) {
      this.parser = parser;
      exception = new AtomicReference<VcsException>();
    }

    @Override
    public void onLineAvailable(String line, Key outputType) {
      if (ProcessOutputTypes.STDOUT.equals(outputType)) {
        try {
          parser.onLine(line);
        }
        catch (VcsException e) {
          exception.set(e);
        }
      }
    }

    public void throwIfException() throws VcsException {
      VcsException e = exception.get();

      if (e != null) {
        throw e;
      }
    }
  }
}
