/*
 * Licensed to CRATE Technology GmbH ("Crate") under one or more contributor
 * license agreements.  See the NOTICE file distributed with this work for
 * additional information regarding copyright ownership.  Crate licenses
 * this file to you under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.  You may
 * obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
 * License for the specific language governing permissions and limitations
 * under the License.
 *
 * However, if you have executed another commercial license agreement
 * with Crate these terms will supersede the license and you may use the
 * software solely pursuant to the terms of the relevant commercial agreement.
 */

package io.crate;


import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.inject.AbstractModule;
import org.elasticsearch.monitor.jvm.JvmInfo;

public class Version {


    // The logic for ID is: XXYYZZAA, where XX is major version, YY is minor version, ZZ is revision, and AA is Beta/RC indicator
    // AA values below 50 are beta builds, and below 99 are RC builds, with 99 indicating a release
    // the (internal) format of the id is there so we can easily do after/before checks on the id

    public static final int V_0_36_03_ID = /*00*/360399;
    public static final Version V_0_36_03 = new Version(V_0_36_03_ID, false,
            org.elasticsearch.Version.V_1_1_1);

    public static final Version CURRENT = V_0_36_03;

    static {
        assert CURRENT.esVersion == org.elasticsearch.Version.CURRENT : "Version must be " +
                "upgraded to [" + org.elasticsearch.Version.CURRENT + "] is still set to [" +
                CURRENT.esVersion + "]";
    }

    public final int id;
    public final byte major;
    public final byte minor;
    public final byte revision;
    public final byte build;
    public final Boolean snapshot;
    public final org.elasticsearch.Version esVersion;

    Version(int id, @Nullable Boolean snapshot, org.elasticsearch.Version esVersion) {
        this.id = id;
        this.major = (byte) ((id / 1000000) % 100);
        this.minor = (byte) ((id / 10000) % 100);
        this.revision = (byte) ((id / 100) % 100);
        this.build = (byte) (id % 100);
        this.snapshot = snapshot;
        this.esVersion = esVersion;
    }

    public boolean snapshot() {
        return snapshot != null && snapshot;
    }

    public boolean after(Version version) {
        return version.id < id;
    }

    public boolean before(Version version) {
        return version.id > id;
    }

    /**
     * Just the version number (without -SNAPSHOT if snapshot).
     */
    public String number() {
        StringBuilder sb = new StringBuilder();
        sb.append(major).append('.').append(minor).append('.').append(revision);
        if (build < 50) {
            sb.append(".Beta").append(build);
        } else if (build < 99) {
            sb.append(".RC").append(build - 50);
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        System.out.println("Version: " + Version.CURRENT + ", Build: " +
                Build.CURRENT.hashShort() + "/" + Build.CURRENT.timestamp() +
                ", ES: " + org.elasticsearch.Version.CURRENT +
                ", JVM: " + JvmInfo.jvmInfo().version() );
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(number());
        if (snapshot()) {
            sb.append("-SNAPSHOT");
        }
        return sb.toString();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Version version = (Version) o;

        if (id != version.id) return false;

        return true;
    }

    @Override
    public int hashCode() {
        return id;
    }

    public static class Module extends AbstractModule {

        private final Version version;

        public Module(Version version) {
            this.version = version;
        }

        @Override
        protected void configure() {
            bind(Version.class).toInstance(version);
        }
    }
}

@@ -1565,20 +1565,20 @@
 nt V_0_3
-6_03
+7_00
 _ID = /*
@@ -1586,11 +1586,11 @@
 0*/3
-603
+700
 99;%0A
@@ -1626,20 +1626,20 @@
 on V_0_3
-6_03
+7_00
  = new V
@@ -1654,21 +1654,20 @@
 _0_3
-6_03
+7_00
 _ID, 
-fals
+tru
 e,%0A 
@@ -1713,13 +1713,14 @@
 1_1_
-1
+0
 );%0A%0A
+%0A
     
@@ -1766,12 +1766,12 @@
 _0_3
-6_03
+7_00
 ;%0A%0A 

increase version for feature branch