package cl.monsoon.s1next.data.api.model;

import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;

import com.google.common.base.Optional;
import com.google.common.base.Preconditions;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public final class ThreadLink implements Parcelable {

    public static final Parcelable.Creator<ThreadLink> CREATOR = new Parcelable.Creator<ThreadLink>() {

        @Override
        public ThreadLink createFromParcel(Parcel source) {
            return new ThreadLink(source);
        }

        @Override
        public ThreadLink[] newArray(int size) {
            return new ThreadLink[size];
        }
    };

    private final String threadId;
    private final int jumpPage;
    private final Optional<String> quotePostId;

    private ThreadLink(Builder builder) {
        this.threadId = builder.threadId;
        this.jumpPage = builder.jumpPage;
        if (builder.quotePostId == null) {
            this.quotePostId = Optional.absent();
        } else {
            this.quotePostId = Optional.of(builder.quotePostId);
        }
    }

    private ThreadLink(Parcel source) {
        threadId = source.readString();
        jumpPage = source.readInt();
        quotePostId = Optional.fromNullable(source.readString());
    }

    /**
     * Parses thread link in order to get the meta info for thread.
     *
     * @param url The thread link.
     */
    public static Optional<ThreadLink> parse(String url) {
        // example: http://bbs.saraba1st.com/2b/forum.php?mod=redirect&goto=findpost&pid=27217893&ptid=1074030
        Pattern pattern = Pattern.compile("ptid=(\\d+)");
        Matcher matcher = pattern.matcher(url);
        if (matcher.find()) {
            Builder builder = new Builder(matcher.group(1));

            matcher.usePattern(Pattern.compile("pid=(\\d+)"));
            if (matcher.find()) {
                builder.quotePostId(matcher.group(1));
            }

            return Optional.of(builder.build());
        }

        // example: http://bbs.saraba1st.com/2b/thread-1074030-1-1.html
        matcher.usePattern(Pattern.compile("thread-(\\d+)-(\\d+)"));
        if (matcher.find()) {
            return Optional.of(new Builder(matcher.group(1))
                    .jumpPage(Integer.parseInt(matcher.group(2)))
                    .build());
        }

        // example:
        // http://bbs.saraba1st.com/2b/forum.php?mod=viewthread&tid=1074030
        matcher.usePattern(Pattern.compile("tid=(\\d+)"));
        if (matcher.find()) {
            Builder builder = new Builder(matcher.group(1));

            // example: http://bbs.saraba1st.com/2b/forum.php?mod=viewthread&tid=1074030&page=7
            matcher.usePattern(Pattern.compile("page=(\\d+)"));
            if (matcher.find()) {
                builder.jumpPage(Integer.parseInt(matcher.group(1)));
            }

            return Optional.of(builder.build());
        }

        // example: http://bbs.saraba1st.com/2b/archiver/tid-1074030.html
        matcher.usePattern(Pattern.compile("tid-(\\d+)"));
        if (matcher.find()) {
            Builder builder = new Builder(matcher.group(1));

            // example: http://bbs.saraba1st.com/2b/archiver/tid-1074030.html?page=7
            matcher.usePattern(Pattern.compile("page=(\\d+)"));
            if (matcher.find()) {
                builder.jumpPage(Integer.parseInt(matcher.group(1)));
            }

            return Optional.of(builder.build());
        }

        return Optional.absent();
    }

    public Optional<String> getQuotePostId() {
        return quotePostId;
    }

    public String getThreadId() {
        return threadId;
    }

    public int getJumpPage() {
        return jumpPage;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(threadId);
        dest.writeInt(jumpPage);
        if (quotePostId.isPresent()) {
            dest.writeString(quotePostId.get());
        } else {
            dest.writeString(null);

        }
    }

    public static class Builder {

        private final String threadId;
        private int jumpPage = 1;
        private String quotePostId;

        public Builder(@NonNull String threadId) {
            this.threadId = Preconditions.checkNotNull(threadId);
        }

        public Builder jumpPage(int jumpPage) {
            this.jumpPage = jumpPage;
            return this;
        }

        public Builder quotePostId(String quotePostId) {
            this.quotePostId = quotePostId;
            return this;
        }

        public ThreadLink build() {
            return new ThreadLink(this);
        }
    }
}

@@ -2478,32 +2478,100 @@
 ead&tid=1074030%0A
+        // or http://bbs.saraba1st.com/2b/archiver/tid-1074030.html%0A
         matcher.
@@ -2601,17 +2601,21 @@
 ile(%22tid
-=
+(=%7C-)
 (%5C%5Cd+)%22)
@@ -2821,487 +2821,13 @@
     
-matcher.usePattern(Pattern.compile(%22page=(%5C%5Cd+)%22));%0A            if (matcher.find()) %7B%0A                builder.jumpPage(Integer.parseInt(matcher.group(1)));%0A            %7D%0A%0A            return Optional.of(builder.build());%0A        %7D%0A%0A        // example: http://bbs.saraba1st.com/2b/archiver/tid-1074030.html%0A        matcher.usePattern(Pattern.compile(%22tid-(%5C%5Cd+)%22));%0A        if (matcher.find()) %7B%0A            Builder builder = new Builder(matcher.group(1));%0A%0A            // example:
+// or
  htt

Combine regular expressions