package com.techshroom.unplanned.core.mod;

import com.google.auto.value.AutoValue;

/**
 * Data about a mod.
 */
@AutoValue
public abstract class ModMetadata {

    public static final Builder builder() {
        return new AutoValue_ModMetadata.Builder();
    }

    @AutoValue.Builder
    public interface Builder {

        default Builder idAndName(String id) {
            return id(id).name(id);
        }

        Builder id(String id);

        Builder name(String name);

        Builder version(String version);

        Builder buildNumber(long buildNumber);

        Builder targetGameVersion(String targetGameVersion);

        ModMetadata build();

    }

    ModMetadata() {
    }

    /**
     * Returns the id of the mod. This id <b>must</b> be unique, if there are
     * non-unique ids there will be a crash!
     * 
     * @return the id of the mod
     */
    public abstract String getId();

    /**
     * Returns the display name of the mod. This may be non-unique.
     * 
     * @return the id of the mod
     */
    public abstract String getName();

    /**
     * Returns the version of the mod. This version may be used on multiple
     * builds of a mod.
     * 
     * @return the version of the mod
     */
    public abstract String getVersion();

    /**
     * Returns the build number of the mod. This must be incremented every time
     * there is a mod upgrade, any changes to the code must increase this
     * number.
     * 
     * @return the build number of the mod
     */
    public abstract long getBuildNumber();

    /**
     * Returns the targeted game version of the mod. A game may choose to load
     * the mod in non-matching versions if the API is non-breaking.
     * 
     * @return the targeted game version of the mod
     */
    public abstract String getTargetGameVersion();

    @Override
    public String toString() {
        return String.format(
                "%s[name=%s,version=%s,buildNumber=%s,targetGameVersion=%s]",
                getId(), getName(), getVersion(), getBuildNumber(),
                getTargetGameVersion());
    }

}

@@ -48,39 +48,156 @@
 ort 
-com.google.auto.value.AutoValue
+static com.google.common.base.Preconditions.checkState;%0A%0Aimport com.google.auto.value.AutoValue;%0Aimport com.techshroom.unplanned.core.util.UDStrings
 ;%0A%0A/
@@ -413,44 +413,86 @@
 lic 
-interface Builder %7B%0A%0A        default
+static abstract class Builder %7B%0A%0A        Builder() %7B%0A        %7D%0A%0A        public
  Bui
@@ -566,32 +566,48 @@
      %7D%0A%0A        
+public abstract 
 Builder id(Strin
@@ -614,32 +614,48 @@
 g id);%0A%0A        
+public abstract 
 Builder name(Str
@@ -666,32 +666,48 @@
 name);%0A%0A        
+public abstract 
 Builder version(
@@ -724,32 +724,48 @@
 sion);%0A%0A        
+public abstract 
 Builder buildNum
@@ -792,24 +792,40 @@
 );%0A%0A        
+public abstract 
 Builder targ
@@ -878,28 +878,689 @@
     
-ModMetadata build();
+abstract ModMetadata autoBuild();%0A%0A        public ModMetadata build() %7B%0A            ModMetadata built = autoBuild();%0A            // TODO semver checks%0A            checkState(UDStrings.count(built.getVersion(), '.') %3E= 2,%0A                    %22version must be semver%22);%0A            checkState(!built.getId().isEmpty(), %22ID cannot be empty%22);%0A            checkState(!built.getName().isEmpty(), %22Name cannot be empty%22);%0A            checkState(!built.getTargetGameVersion().isEmpty(),%0A                    %22Target game version cannot be empty%22);%0A            checkState(built.getBuildNumber() %3E= 0,%0A                    %22Build number must be positive%22);%0A            return built;%0A        %7D
 %0A%0A  
@@ -1627,24 +1627,47 @@
 d of the mod
+, which cannot be empty
 . This id %3Cb
@@ -1678,16 +1678,23 @@
 t%3C/b%3E be
+%0A     *
  unique,
@@ -1706,23 +1706,16 @@
 here are
-%0A     *
  non-uni
@@ -1873,32 +1873,55 @@
  name of the mod
+, which cannot be empty
 . This may be no
@@ -1917,16 +1917,23 @@
 s may be
+%0A     *
  non-uni
@@ -2070,22 +2070,60 @@
  the mod
-. This
+, which MUST be in semver style. This%0A     *
  version
@@ -2146,23 +2146,16 @@
 multiple
-%0A     *
  builds 
@@ -2310,16 +2310,40 @@
  the mod
+, which must be positive
 . This m
@@ -2348,16 +2348,23 @@
  must be
+%0A     *
  increme
@@ -2378,23 +2378,16 @@
 ery time
-%0A     *
  there i
@@ -2426,16 +2426,23 @@
 the code
+%0A     *
  must in
@@ -2452,23 +2452,16 @@
 ase this
-%0A     *
  number.
@@ -2627,11 +2627,42 @@
  mod
-. A
+, which may not be empty. A%0A     *
  gam
@@ -2681,23 +2681,16 @@
  to load
-%0A     *
  the mod
@@ -2728,16 +2728,23 @@
 e API is
+%0A     *
  non-bre
@@ -2895,16 +2895,22 @@
  public 
+final 
 String t

Add some checks for ModMetadata