// 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 com.cloud.network;

import java.net.URI;
import java.net.URISyntaxException;

import com.cloud.utils.exception.CloudRuntimeException;

/**
 * Network includes all of the enums used within networking.
 * 
 */
public class Networks {

    public enum RouterPrivateIpStrategy {
        None,
        DcGlobal, // global to data center
        HostLocal;

        public static String DummyPrivateIp = "169.254.1.1";
    }

    /**
     * Different ways to assign ip address to this network.
     */
    public enum Mode {
        None,
        Static,
        Dhcp,
        ExternalDhcp;
    };

    public enum AddressFormat {
        Ip4,
        Ip6,
        DualStack
    }

    /**
     * Different types of broadcast domains.
     */
    public enum BroadcastDomainType {
        Native(null, null) {
            @Override
            public <T> URI toUri(T value) {
                try {
                    if (value.toString().contains("://"))
                        return new URI(value.toString());
                    else
                        // strange requirement but this is how the code expects it
                        return new URI("vlan://" + value.toString());
                } catch (URISyntaxException e) {
                    throw new CloudRuntimeException("Unable to convert to broadcast URI: " + value);
                }
            }
        },
        Vlan("vlan", Integer.class) {
            @Override
            public <T> URI toUri(T value) {
                try {
                    if (value.toString().contains("://"))
                        return new URI(value.toString());
                    else
                        return new URI("vlan://" + value.toString());
                } catch (URISyntaxException e) {
                    throw new CloudRuntimeException(
                            "Unable to convert to broadcast URI: " + value);
                }
            }
        },
        Vswitch("vs", String.class),
        LinkLocal(null, null),
        Vnet("vnet", Long.class),
        Storage("storage", Integer.class),
        Lswitch("lswitch", String.class) {
            @Override
            public <T> URI toUri(T value) {
                try {
                    return new URI("lswitch",value.toString(),null,null);
                } catch (URISyntaxException e) {
                    throw new CloudRuntimeException(
                            "Unable to convert to broadcast URI: " + value);
                }
            }

            /**
             * gets scheme specific part instead of host
             */
            @Override
            public String getValueFrom(URI uri) {
                return uri.getSchemeSpecificPart();
            }
        },
        Mido("mido", String.class),
        Pvlan("pvlan", String.class),
        UnDecided(null, null);

        private final String scheme;
        private final Class<?> type;

        private BroadcastDomainType(String scheme, Class<?> type) {
            this.scheme = scheme;
            this.type = type;
        }

        /**
         * @return scheme to be used in broadcast uri. Null indicates that this
         *         type does not have broadcast tags.
         */
        public String scheme() {
            return scheme;
        }

        /**
         * @return type of the value in the broadcast uri. Null indicates that
         *         this type does not have broadcast tags.
         */
        public Class<?> type() {
            return type;
        }

        /**
         * The default implementation of toUri returns an uri with the scheme and value as host
         *
         * @param value will be put in the host field
         * @return the resulting URI
         */
        public <T> URI toUri(T value) {
            try {
                return new URI(scheme + "://" + value.toString());
            } catch (URISyntaxException e) {
                throw new CloudRuntimeException(
                        "Unable to convert to broadcast URI: " + value);
            }
        }

        /**
         * get the enum value from this uri
         *
         * @param uri to get the scheme value from
         * @return the scheme as BroadcastDomainType
         */
        public static BroadcastDomainType getSchemeValue(URI uri) {
            return toEnumValue(uri.getScheme());
        }

        /**
         * gets the type from a string encoded uri
         *
         * @param str the uri string
         * @return the scheme as BroadcastDomainType
         * @throws URISyntaxException when the string can not be converted to URI
         */
        public static BroadcastDomainType getTypeOf(String str)
                throws URISyntaxException {
            if (com.cloud.dc.Vlan.UNTAGGED.equalsIgnoreCase(str)) {
                return Native;
            }
            return getSchemeValue(new URI(str));
        }

        /**
         * converts a String to a BroadcastDomainType
         *
         * @param scheme convert a string representation to a BroacastDomainType
         * @return the value of this
         */
        public static BroadcastDomainType toEnumValue(String scheme) {
            if (scheme == null) {
                return UnDecided;
            }
            for (BroadcastDomainType type : values()) {
                if (scheme.equalsIgnoreCase(type.scheme())) {
                    return type;
                }
            }
            return UnDecided;
        }

        /**
         * The default implementation of getValueFrom returns the host part of the uri
         *
         * @param uri to get the value from
         * @return the host part as String
         */
        public String getValueFrom(URI uri) {
            return uri.getHost();
        }

        /**
         * get the BroadcastDomain value from an arbitrary URI
         * TODO what when the uri is useless
         *
         * @param uri the uri
         * @return depending on the scheme/BroadcastDomainType
         */
        public static String getValue(URI uri) {
            return getSchemeValue(uri).getValueFrom(uri);
        }

        /**
         * get the BroadcastDomain value from an arbitrary String
         * TODO what when the uriString is useless
         *
         * @param uriString the string encoded uri
         * @return depending on the scheme/BroadcastDomainType
         * @throws URISyntaxException the string is not even an uri
         */
        public static String getValue(String uriString)
                throws URISyntaxException {
            return getValue(new URI(uriString));
        }

        /**
         * encode a string into a BroadcastUri
         * @param candidate the input string
         * @return an URI containing an appropriate (possibly given) scheme and the value
         */
        public static URI fromString(String candidate) {
            try {
                Long.parseLong(candidate);
                return Vlan.toUri(candidate);
            } catch (NumberFormatException nfe) {
                if (com.cloud.dc.Vlan.UNTAGGED.equalsIgnoreCase(candidate)) {
                    return Native.toUri(candidate);
                }
                try {
                    URI uri = new URI(candidate);
                    BroadcastDomainType tiep = getSchemeValue(uri);
                    if (tiep.scheme.equals(uri.getScheme())) {
                        return uri;
                    } else {
                        throw new CloudRuntimeException("string '" + candidate + "' has an unknown BroadcastDomainType.");
                    }
                } catch (URISyntaxException e) {
                    throw new CloudRuntimeException("string is not a broadcast URI: " + candidate);
                }
            }
        }
    };

    /**
     * Different types of network traffic in the data center.
     */
    public enum TrafficType {
        None,
        Public,
        Guest,
        Storage,
        Management,
        Control,
        Vpn;

        public static boolean isSystemNetwork(TrafficType trafficType) {
            if (Storage.equals(trafficType) || Management.equals(trafficType)
                    || Control.equals(trafficType)) {
                return true;
            }
            return false;
        }

        public static TrafficType getTrafficType(String type) {
            if ("Public".equals(type)) {
                return Public;
            } else if ("Guest".equals(type)) {
                return Guest;
            } else if ("Storage".equals(type)) {
                return Storage;
            } else if ("Management".equals(type)) {
                return Management;
            } else if ("Control".equals(type)) {
                return Control;
            } else if ("Vpn".equals(type)) {
                return Vpn;
            } else {
                return None;
            }
        }
    };

    public enum IsolationType {
        None(null, null),
        Ec2("ec2", String.class),
        Vlan("vlan", Integer.class) {
            @Override
            public <T> URI toUri(T value) {
                try {
                    if (value.toString().contains(":"))
                        return new URI(value.toString());
                    else
                        return new URI("vlan", value.toString(), null, null);
                } catch (URISyntaxException e) {
                    throw new CloudRuntimeException(
                            "Unable to convert to isolation URI: " + value);
                }
            }
        },
        Vswitch("vs", String.class),
        Undecided(null, null),
        Vnet("vnet", Long.class);

        private final String scheme;
        private final Class<?> type;

        private IsolationType(String scheme, Class<?> type) {
            this.scheme = scheme;
            this.type = type;
        }

        public String scheme() {
            return scheme;
        }

        public Class<?> type() {
            return type;
        }

        public <T> URI toUri(T value) {
            try {
                return new URI(scheme + "://" + value.toString());
            } catch (URISyntaxException e) {
                throw new CloudRuntimeException(
                        "Unable to convert to isolation type URI: " + value);
            }
        }
    }

    public enum BroadcastScheme {
        Vlan("vlan"),
        VSwitch("vswitch");

        private final String scheme;

        private BroadcastScheme(String scheme) {
            this.scheme = scheme;
        }

        @Override
        public String toString() {
            return scheme;
        }
    }
}
