/*
 * Copyright 2014-present Open Networking Foundation
 *
 * Licensed 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.onosproject.net;

import com.google.common.base.Objects;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.primitives.UnsignedLongs;

import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Representation of a port number.
 */
public final class PortNumber {

    public static final PortNumber P0 = portNumber(0);

    // TODO: revisit the max and the logical port value assignments

    static final long MAX_NUMBER = (2L * Integer.MAX_VALUE) + 1;

    static final long IN_PORT_NUMBER = -8L;
    static final long TABLE_NUMBER = -7L;
    static final long NORMAL_NUMBER = -6L;
    static final long FLOOD_NUMBER = -5L;
    static final long ALL_NUMBER = -4L;
    static final long CONTROLLER_NUMBER = -3L;
    static final long LOCAL_NUMBER = -2L;
    static final long ANY_NUMBER = -1L;

    public static final long NO_DISPLAY_NUMBER = -1L;

    /**
     * Logical PortNumbers.
     */
    public enum Logical {
        IN_PORT(IN_PORT_NUMBER),
        TABLE(TABLE_NUMBER),
        NORMAL(NORMAL_NUMBER),
        FLOOD(FLOOD_NUMBER),
        ALL(ALL_NUMBER),
        LOCAL(LOCAL_NUMBER),
        CONTROLLER(CONTROLLER_NUMBER),
        ANY(ANY_NUMBER);

        private final long number;
        private final PortNumber instance;

        public long number() {
            return number;
        }

        /**
         * PortNumber instance for the logical port.
         *
         * @return {@link PortNumber}
         */
        public PortNumber instance() {
            return instance;
        }

        Logical(long number) {
            this.number = number;
            this.instance = new PortNumber(number);
        }
    }

    public static final PortNumber IN_PORT = new PortNumber(IN_PORT_NUMBER);
    public static final PortNumber TABLE = new PortNumber(TABLE_NUMBER);
    public static final PortNumber NORMAL = new PortNumber(NORMAL_NUMBER);
    public static final PortNumber FLOOD = new PortNumber(FLOOD_NUMBER);
    public static final PortNumber ALL = new PortNumber(ALL_NUMBER);
    public static final PortNumber LOCAL = new PortNumber(LOCAL_NUMBER);
    public static final PortNumber CONTROLLER = new PortNumber(CONTROLLER_NUMBER);
    public static final PortNumber ANY = new PortNumber(ANY_NUMBER);

    // lazily populated Logical port number to PortNumber
    static final Supplier<Map<Long, Logical>> LOGICAL = Suppliers.memoize(() -> {
            Builder<Long, Logical> builder = ImmutableMap.builder();
            for (Logical lp : Logical.values()) {
                builder.put(lp.number(), lp);
            }
            return builder.build();
        });

    private final long number;
    private final String name;
    private final boolean hasName;

    // Public creation is prohibited
    private PortNumber(long number) {
        this.number = number;
        this.name = UnsignedLongs.toString(number);
        this.hasName = false;
    }

    private PortNumber(long number, String name) {
        this.number = number;
        this.name = name;
        this.hasName = true;
    }

    /**
     * Returns the port number representing the specified long value.
     *
     * @param number port number as long value
     * @return port number
     */
    public static PortNumber portNumber(long number) {
        return new PortNumber(number);
    }

    /**
     * Returns the port number representing the specified string value.
     *
     * @param string port number as decimal, hexadecimal, or octal number string
     * @return port number
     */
    public static PortNumber portNumber(String string) {
        return new PortNumber(UnsignedLongs.decode(string));
    }

    /**
     * Returns the port number representing the specified long value and name.
     *
     * @param number port number as long value
     * @param name port name as string value
     * @return port number
     */
    public static PortNumber portNumber(long number, String name) {
        return new PortNumber(number, name);
    }

    /**
     * Returns PortNumber instance from String representation.
     *
     * @param s String representation equivalent to {@link PortNumber#toString()}
     * @return {@link PortNumber} instance
     * @throws IllegalArgumentException if given String was malformed
     */
    public static PortNumber fromString(String s) {
        checkNotNull(s);
        checkArgument(!s.isEmpty(), "cannot be empty");

        if (isAsciiDecimal(s.charAt(0))) {
            // unsigned decimal string
            return portNumber(s);
        } else if (s.startsWith("[")) {
            // named PortNumber
            Matcher matcher = NAMED.matcher(s);
            checkArgument(matcher.matches(), "Invalid named PortNumber %s", s);

            String name = matcher.group("name");
            String num = matcher.group("num");
            return portNumber(UnsignedLongs.parseUnsignedLong(num), name);
        }

        // Logical
        if (s.startsWith("UNKNOWN(") && s.endsWith(")")) {
            return portNumber(s.substring("UNKNOWN(".length(), s.length() - 1));
        } else {
            return Logical.valueOf(s).instance;
        }
    }

    /**
     * Indicates whether or not this port number is a reserved logical one or
     * whether it corresponds to a normal physical port of a device or NIC.
     *
     * @return true if logical port number
     */
    public boolean isLogical() {
        if (hasName) {
            return false;
        } else {
            return (number < 0 || number > MAX_NUMBER);
        }
    }

    /**
     * Returns the backing long value.
     *
     * @return port number as long
     */
    public long toLong() {
        return number;
    }

    /**
     * Returns the backing string value.
     *
     * @return port name as string value
     */
    public String name() {
        return name;
    }

    /**
     * Indicates whether this port number was created with a port name,
     * or only with a number.
     *
     * @return true if port was created with name
     */
    public boolean hasName() {
        return hasName;
    }

    private String decodeLogicalPort() {
        Logical logical = LOGICAL.get().get(number);
        if (logical != null) {
            // enum name
            return logical.toString();
        }
        return String.format("%s", UnsignedLongs.toString(number));
    }

    private String decodeLogicalPortExtended() {
        Logical logical = LOGICAL.get().get(number);
        if (logical != null) {
            // enum name
            return logical.toString();
        }
        return String.format("UNKNOWN(%s)", UnsignedLongs.toString(number));
    }


    /**
     * Regular expression to match String representation of named PortNumber.
     *
     * Format: "[name](num:unsigned decimal string)"
     */
    private static final Pattern NAMED = Pattern.compile("^\\[(?<name>.*)\\]\\((?<num>\\d+)\\)$");

    private static boolean isAsciiDecimal(char c) {
        return '0' <= c  && c <= '9';
    }

    @Override
    public String toString() {
        if (isLogical()) {
            return decodeLogicalPortExtended();
        } else if (hasName()) {
            // named port
            if (number == NO_DISPLAY_NUMBER) {
                return String.format("[%s]", name);
            } else {
                return String.format("[%s](%d)", name, number);
            }
        } else {
            // unsigned decimal string
            return name;
        }
    }

    // toString method that does not use the name.
    // if it is a logical port will use either the enum or the number
    // else if it has a name returns just the number
    // else it does not have a name, it returns the number because name == number
    public String toStringWithoutName() {
        if (isLogical()) {
            return decodeLogicalPort();
        }
        // Either named port or port without name
        return UnsignedLongs.toString(number);
    }

    @Override
    public int hashCode() {
        return Long.hashCode(number);
    }

    public int hashCodeExtended() {
        return Objects.hashCode(number, hasName() ? name : 0);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof PortNumber) {
            final PortNumber other = (PortNumber) obj;
            return this.number == other.number;
        }
        return false;
    }

    /**
     * Indicates whether some other PortNumber object is equal to this one
     * including it's name.
     *
     * @param that other {@link PortNumber} instance to compare
     * @return true if equal, false otherwise
     */
    public boolean exactlyEquals(PortNumber that) {
        if (this == that) {
            return true;
        }

        return this.equals(that) &&
               this.hasName == that.hasName &&
               Objects.equal(this.name, that.name);
    }
}
