/*
*
* 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 Qpid Gentools v.0.1 - do not modify.
* Supported AMQP versions:
* 0-9
* 0-91
* 8-0
*/

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;
import java.util.concurrent.ConcurrentHashMap;

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

    private 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);

    public static final ProtocolVersion v0_9 = new ProtocolVersion((byte)0,(byte)9);
    public static final ProtocolVersion v0_91 = new ProtocolVersion((byte)0,(byte)91);
    public static final ProtocolVersion v0_8 = new ProtocolVersion((byte)8,(byte)0);

    private static final Map<ProtocolVersion, ProtocolVersion> INSTANCES = new ConcurrentHashMap<ProtocolVersion,ProtocolVersion>();

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

        versions.add(v0_10);
        _nameToVersionMap.put("0-10", v0_10);
        versions.add(v0_9);
        _nameToVersionMap.put("0-9", v0_9);
        versions.add(v0_91);
        _nameToVersionMap.put("0-91", v0_91);
        versions.add(v0_8);
        _nameToVersionMap.put("8-0", v0_8);
        _supportedVersions = Collections.unmodifiableSortedSet(versions);

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

        _defaultVersion = (systemDefinedVersion == null)
                              ? getLatestSupportedVersion()
                              : systemDefinedVersion;
        INSTANCES.put(v0_10,v0_10);
        INSTANCES.put(v0_9,v0_9);
        INSTANCES.put(v0_91,v0_91);
        INSTANCES.put(v0_8, v0_8);
    }

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

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

    public static ProtocolVersion defaultProtocolVersion()
    {
        return _defaultVersion;
    }

    public static ProtocolVersion get(byte majorVersion, byte minorVersion)
    {
        ProtocolVersion pv = new ProtocolVersion(majorVersion, minorVersion);
        ProtocolVersion instance = INSTANCES.get(pv);
        return instance == null ? pv : instance;
    }


}
