package com.atlassian.bitbucket.content;

import com.google.common.collect.ImmutableList;
import org.apache.commons.collections.CollectionUtils;

import javax.annotation.Nonnull;
import java.util.List;

public class SimpleDiffHunk implements DiffHunk {

    private final int destinationLine;
    private final int destinationSpan;
    private final List<DiffSegment> segments;
    private final int sourceLine;
    private final int sourceSpan;
    private final boolean truncated;

    private SimpleDiffHunk(int sourceLine, int sourceSpan, int destinationLine, int destinationSpan,
                           boolean truncated, List<DiffSegment> segments) {
        this.destinationLine = destinationLine;
        this.destinationSpan = destinationSpan;
        this.segments = segments;
        this.sourceLine = sourceLine;
        this.sourceSpan = sourceSpan;
        this.truncated = truncated;
    }

    @Override
    public int getDestinationLine() {
        return destinationLine;
    }

    @Override
    public int getDestinationSpan() {
        return destinationSpan;
    }

    @Nonnull
    @Override
    public List<DiffSegment> getSegments() {
        return segments;
    }

    @Override
    public int getSourceLine() {
        return sourceLine;
    }

    @Override
    public int getSourceSpan() {
        return sourceSpan;
    }

    @Override
    public boolean isTruncated() {
        return truncated;
    }

    public static final class Builder {

        private int destinationLine;
        private int destinationSpan;
        private ImmutableList.Builder<DiffSegment> segments;
        private int sourceLine;
        private int sourceSpan;
        private boolean truncated;

        public Builder() {
            segments = ImmutableList.builder();
        }

        public Builder(DiffHunk hunk) {
            this();

            destinationLine = hunk.getDestinationLine();
            destinationSpan = hunk.getDestinationSpan();
            sourceLine = hunk.getSourceLine();
            sourceSpan = hunk.getSourceSpan();
            truncated = hunk.isTruncated();

            List<DiffSegment> s = hunk.getSegments();
            if (CollectionUtils.isNotEmpty(s)) {
                segments.addAll(s);
            }
        }

        public SimpleDiffHunk build() {
            return new SimpleDiffHunk(sourceLine, sourceSpan, destinationLine, destinationSpan,
                    truncated, segments.build());
        }

        public Builder destinationLine(int value) {
            destinationLine = value;

            return this;
        }

        public Builder destinationSpan(int value) {
            destinationSpan = value;

            return this;
        }

        public Builder segment(DiffSegment value) {
            segments.add(value);

            return this;
        }

        public Builder segments(DiffSegment value, DiffSegment... values) {
            segments.add(value)
                    .add(values);

            return this;
        }

        public Builder segments(Iterable<DiffSegment> value) {
            if (value != null) {
                segments.addAll(value);
            }

            return this;
        }

        public Builder sourceLine(int value) {
            sourceLine = value;

            return this;
        }

        public Builder sourceSpan(int value) {
            sourceSpan = value;

            return this;
        }

        public Builder truncated(boolean value) {
            truncated = value;

            return this;
        }
    }
}
