package com.github.qrokodial.sparkle.utilities.versioning;

import java.util.Optional;

public class Version {
    private int major;
    private int minor;
    private int revision;
    private int build;
    private Stage stage;

    public enum Stage {
        /**
         * For final releases of the particular version.
         */
        RELEASE,

        /**
         * A release candidate. You think this *might* be suitable for a final release, but you still want to do more
         * testing.
         */
        RC,

        /**
         * A beta release. This typically means you have all your features in and you're just working on bug fixes.
         */
        BETA,

        /**
         * Alpha releases are for early on in development where you still have things to do.
         */
        ALPHA,

        /**
         * When you have so much left to do and so much left to change you feel funny calling it an alpha release.
         */
        GAMMA;

        /**
         * Attempts to get the stage from a string.
         *
         * @param string the string
         * @return the stage, if successful
         */
        public static Optional<Stage> fromString(String string) {
            return Optional.ofNullable(valueOf(string.toUpperCase()));
        }
    }

    /**
     * Instantiates the class.
     *
     * @param major
     * @param minor
     * @param revision
     * @param stage
     */
    public Version(int major, int minor, int revision, int build, Stage stage) {
        this.major = major;
        this.minor = minor;
        this.revision = revision;
        this.stage = stage;
        this.build = build;
    }

    /**
     * @return the major version number
     */
    public int getMajor() {
        return major;
    }

    /**
     * @return the minor version number
     */
    public int getMinor() {
        return minor;
    }

    /**
     * @return the revision version number
     */
    public int getRevision() {
        return revision;
    }

    /**
     * @return the build version number
     */
    public int getBuild() {
        return build;
    }

    /**
     * @return the stage of the version
     */
    public Stage getStage() {
        return stage;
    }

    /**
     * @return the string representation of the class
     */
    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append(getMajor());
        builder.append(".");
        builder.append(getMinor());
        builder.append(".");
        builder.append(getRevision());

        if (!getStage().equals(Stage.RELEASE)) {
            builder.append(" ");
            builder.append(getStage());
        }

        if (getBuild() != 0) {
            builder.append(" Build ");
            builder.append(getBuild());
        }

        return builder.toString();
    }

    /**
     * Attempts to convert a string into a {@link Version}.
     *
     * @param version the string
     * @return the version, if successful
     */
    public static Optional<Version> fromString(String version) {
        String[] split = version.toLowerCase().split(" ");

        if (split.length < 1 || split.length > 4) {
            return Optional.empty();
        }

        String[] numbers = split[0].split(".");

        int major;
        int minor;
        int revision = 0;

        if (numbers.length < 2 || numbers.length > 3) {
            return Optional.empty();
        }

        try {
            major = Integer.parseInt(numbers[0]);
            minor = Integer.parseInt(numbers[1]);
            if (numbers.length == 3) {
                revision = Integer.parseInt(numbers[2]);
            }
        } catch (NumberFormatException e) {
            return Optional.empty();
        }

        Optional<Stage> stage;

        if (split.length == 1) {
            stage = Optional.of(Stage.RELEASE);
        } else {
            stage = Stage.fromString(split[1]);
        }

        int build;

        if (stage.isPresent() && split.length == 4) {
            if (!split[2].contentEquals("build")) {
                return Optional.empty();
            }

            try {
                build = Integer.parseInt(split[3]);
            } catch (NumberFormatException e) {
                return Optional.empty();
            }
        } else if (stage.isPresent() && split.length == 3) {
            if (!split[1].contentEquals("build")) {
                return Optional.empty();
            }

            try {
                build = Integer.parseInt(split[4]);
            } catch (NumberFormatException e) {
                return Optional.empty();
            }
        } else {
            return Optional.empty();
        }

        return Optional.of(new Version(major, minor, revision, build, stage.get()));
    }
}

@@ -3294,16 +3294,18 @@
 .split(%22
+%5C%5C
 .%22);%0A%0A  
@@ -3993,16 +3993,20 @@
 nt build
+ = 0
 ;%0A%0A     
@@ -4400,116 +4400,8 @@
 ) %7B%0A
-            if (!split%5B1%5D.contentEquals(%22build%22)) %7B%0A                return Optional.empty();%0A            %7D%0A%0A
     
@@ -4461,17 +4461,17 @@
 t(split%5B
-4
+2
 %5D);%0A    
@@ -4582,62 +4582,8 @@
    %7D
- else %7B%0A            return Optional.empty();%0A        %7D
 %0A%0A  

Fix Version#fromString