package com.atlassian.stash.internal.scm.git.command.status;

import com.atlassian.stash.internal.scm.git.DefaultGitStatus;
import com.atlassian.stash.internal.scm.git.GitFileStatus;
import com.atlassian.stash.internal.scm.git.GitStatus;
import com.atlassian.bitbucket.scm.CommandOutputHandler;
import com.atlassian.bitbucket.util.PageRequest;
import com.atlassian.utils.process.LineOutputHandler;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * @since 2.0
 */
public class StatusOutputHandler extends LineOutputHandler implements CommandOutputHandler<Void> {

    static final String COPY_SEPARATOR = " -> ";

    private final PageRequest pageRequest;
    private final StatusCallback callback;

    public StatusOutputHandler(PageRequest pageRequest, StatusCallback callback) {
        this.pageRequest = pageRequest;
        this.callback = callback;
    }

    @Override
    public Void getOutput() {
        return null;
    }

    @Override
    protected void processLine(int lineNum, String line) {
        int start = pageRequest.getStart(), end = start + pageRequest.getLimit();
        if (start <= lineNum && lineNum < end) {
            callback.onStatus(parseLine(line));
        } else if (lineNum > end) {
            cancelProcess();
        }
    }

    private GitStatus parseLine(String line) {
        checkNotNull(line, "line");
        checkArgument(line.length() > 4, "Invalid status line: %s", line);

        GitFileStatus statusIndex = GitFileStatus.fromStatus(line.substring(0, 1));
        GitFileStatus statusWorkTree = GitFileStatus.fromStatus(line.substring(1, 2));

        String path = line.substring(3);

        int copy = path.indexOf(COPY_SEPARATOR);
        if (copy == -1) {
            return new DefaultGitStatus(statusIndex, statusWorkTree, path);
        } else {
            String srcPath = path.substring(copy + COPY_SEPARATOR.length());
            path = path.substring(0, copy);
            return new DefaultGitStatus(statusIndex, statusWorkTree, path, srcPath);
        }
    }

}
