#set( $filename = "ProtocolVersion.java" )
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF 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.
*
*/

/*
* This file is auto-generated by $generator - do not modify.
* Supported AMQP versions:
#foreach( $version in $model.getVersionSet() )
* $version.getMajor()-$version.getMinor()
#end
*/

package org.apache.qpid.framing;

import java.util.SortedSet;
import java.util.Collections;
import java.util.TreeSet;
import java.util.Map;
import java.util.HashMap;

public class ProtocolVersion  implements Comparable
{
    private final byte _majorVersion;
    private final byte _minorVersion;
    private final String _stringFormat;

    public ProtocolVersion(byte majorVersion, byte minorVersion)
    {
        _majorVersion = majorVersion;
        _minorVersion = minorVersion;
        _stringFormat = _majorVersion+"-"+_minorVersion;
    }

    public byte getMajorVersion()
    {
        return _majorVersion;
    }

    public byte getMinorVersion()
    {
        return _minorVersion;
    }

    public byte getActualMinorVersion()
    {
        return _minorVersion > 90 ? (byte) (_minorVersion / 10) : _minorVersion;
    }

    public byte getRevisionVersion()
    {
        return _minorVersion > 90 ? (byte) (_minorVersion % 10) : (byte) 0;
    }

    public String toString()
    {
        return _stringFormat;
    }

    public int compareTo(Object o)
    {
        ProtocolVersion pv = (ProtocolVersion) o;

        /* 
         * 0-8 has it's major and minor numbers the wrong way round (it's actually 8-0)...
         * so we need to deal with that case specially
         */

        if((_majorVersion == (byte) 8) && (_minorVersion == (byte) 0))
        {
            ProtocolVersion fixedThis = new ProtocolVersion(_minorVersion, _majorVersion);
            return fixedThis.compareTo(pv);
        }

        if((pv.getMajorVersion() == (byte) 8) && (pv.getMinorVersion() == (byte) 0))
        {
            ProtocolVersion fixedOther = new ProtocolVersion(pv.getMinorVersion(), pv.getMajorVersion());
            return this.compareTo(fixedOther);
        }

        if(_majorVersion > pv.getMajorVersion())
        {
            return 1;
        }
        else if(_majorVersion < pv.getMajorVersion())
        {
            return -1;
        }
        else if(_minorVersion > pv.getMinorVersion())
        {
            return 1;
        }
        else if(getMinorVersion() < pv.getMinorVersion())
        {
            return -1;
        }
        else
        {
            return 0;
        }

    }

    public boolean equals(Object o)
    {
        return o != null && (o == this || (compareTo(o) == 0));
    }

    public int hashCode()
    {
        return (0xFF & (int)_minorVersion) | ((0xFF & (int)_majorVersion) << 8);
    }

    public boolean isSupported()
    {
        return _supportedVersions.contains(this);
    }

    public static ProtocolVersion getLatestSupportedVersion()
    {
        return _supportedVersions.last();
    }

    private static final SortedSet<ProtocolVersion> _supportedVersions;
    private static final Map<String, ProtocolVersion> _nameToVersionMap =
                             new HashMap<String, ProtocolVersion>();
    private static final ProtocolVersion _defaultVersion;

    public static final ProtocolVersion v0_10 = new ProtocolVersion((byte)0,(byte)10);

#foreach( $version in $model.getVersionSet() )
#set( $versionId = "v$version.getMajor()_$version.getMinor()" )
    public static final ProtocolVersion $versionId = new ProtocolVersion((byte)$version.getMajor(),(byte)$version.getMinor());
#end

    static
    {
        SortedSet<ProtocolVersion> versions = new TreeSet<ProtocolVersion>();

        versions.add(v0_10);
        _nameToVersionMap.put("0-10", v0_10);
#foreach( $version in $model.getVersionSet() )
#set( $versionId = "v$version.getMajor()_$version.getMinor()" )
        versions.add($versionId);
        _nameToVersionMap.put("${version.getMajor()}-${version.getMinor()}", $versionId);
#end
        _supportedVersions = Collections.unmodifiableSortedSet(versions);

        ProtocolVersion systemDefinedVersion =
            _nameToVersionMap.get(System.getProperty("org.apache.qpid.amqp_version"));

        _defaultVersion = (systemDefinedVersion == null)
                              ? getLatestSupportedVersion()
                              : systemDefinedVersion;
    }

    public static SortedSet<ProtocolVersion> getSupportedProtocolVersions()
    {
        return _supportedVersions;
    }

    public static ProtocolVersion parse(String name)
    {
        return _nameToVersionMap.get(name);
    }

    public static ProtocolVersion defaultProtocolVersion()
    {
        return _defaultVersion;
    }

}
