/*
 *  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.
 */
package org.apache.harmony.xnet.provider.jsse;

import java.util.Hashtable;

/**
 * 
 * Represents Protocol Version
 */
public class ProtocolVersion {
    /**
     * Protocols supported by this provider implementation
     */
    public static final String[] supportedProtocols = new String[] { "TLSv1",
            "SSLv3" };

    private static Hashtable<String, ProtocolVersion> protocolsByName = new Hashtable<String, ProtocolVersion>(4);

    /**
     * 
     * Returns true if protocol version is supported
     * 
     * @param version
     */
    public static boolean isSupported(byte[] version) {
        if (version[0] != 3 || (version[1] != 0 && version[1] != 1)) {
            return false;
        }
        return true;
    }

    /**
     * Returns ProtocolVersion
     * 
     * @param version
     * @return
     */
    public static ProtocolVersion getByVersion(byte[] version) {
        if (version[0] == 3) {
            if (version[1] == 1) {
                return TLSv1;
            }
            if (version[1] == 0) {
                return SSLv3;
            }
        }
        return null;
    }

    /**
     * Returns true if provider supports protocol version
     * 
     * @param name
     * @return
     */
    public static boolean isSupported(String name) {
        return protocolsByName.containsKey(name);
    }

    /**
     * Returns ProtocolVersion
     * 
     * @param name
     * @return
     */
    public static ProtocolVersion getByName(String name) {
        return protocolsByName.get(name);
    }

    /**
     * Highest protocol version supported by provider implementation
     * 
     * @param protocols
     * @return
     */
    public static ProtocolVersion getLatestVersion(String[] protocols) {
        if (protocols == null || protocols.length == 0) {
            return null;
        }
        ProtocolVersion latest = getByName(protocols[0]);
        ProtocolVersion current;
        for (int i = 1; i < protocols.length; i++) {
            current = getByName(protocols[i]);
            if (current == null) {
                continue;
            }
            if ((latest == null)
                    || (latest.version[0] < current.version[0])
                    || (latest.version[0] == current.version[0] && latest.version[1] < current.version[1])) {
                latest = current;
            }
        }
        return latest;

    }

    /**
     * SSL 3.0 protocol version
     */
    public static ProtocolVersion SSLv3 = new ProtocolVersion("SSLv3",
            new byte[] { 3, 0 });

    /**
     * TLS 1.0 protocol version
     */
    public static ProtocolVersion TLSv1 = new ProtocolVersion("TLSv1",
            new byte[] { 3, 1 });

    static {
        protocolsByName.put(SSLv3.name, SSLv3);
        protocolsByName.put(TLSv1.name, TLSv1);
        protocolsByName.put("SSL", SSLv3);
        protocolsByName.put("TLS", TLSv1);
    }

    /**
     * Protocol name
     */
    public final String name;

    /**
     * Protocol version as byte array
     */
    public final byte[] version;

    private ProtocolVersion(String name, byte[] version) {
        this.name = name;
        this.version = version;
    }

    /**
     * Compares this ProtocolVersion to the specified object.
     */
    @Override
    public boolean equals(Object o) {
        if (o instanceof ProtocolVersion
                && this.version[0] == ((ProtocolVersion) o).version[0]
                && this.version[1] == ((ProtocolVersion) o).version[1]) {
            return true;
        }
        return false;
    }
}