/*
 *  Copyright 2015 Open Networking Laboratory
 *
 *  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.ui.topo;

/**
 * Designates a badge to be applied to a node in the topology view.
 */
public final class NodeBadge {

    private static final String EMPTY = "";

    /** Designates the badge status. */
    public enum Status {
        INFO("i"),
        WARN("w"),
        ERROR("e");

        private String code;

        Status(String code) {
            this.code = code;
        }

        @Override
        public String toString() {
            return "{" + code + "}";
        }

        /* Returns the status code in string form. */
        public String code() {
            return code;
        }
    }

    private final Status status;
    private final boolean isGlyph;
    private final String text;
    private final String message;

    // only instantiated through static methods.
    private NodeBadge(Status status, boolean isGlyph, String text, String message) {
        this.status = status == null ? Status.INFO : status;
        this.isGlyph = isGlyph;
        this.text = text;
        this.message = message;
    }

    @Override
    public String toString() {
        return "{Badge " + status +
                " (" + text + ")" +
                (isGlyph ? "*G " : " ") +
                "\"" + message + "\"}";
    }

    /**
     * Returns the badge status.
     *
     * @return badge status
     */
    public Status status() {
        return status;
    }

    /**
     * Returns true if the text for this badge designates a glyph ID.
     *
     * @return true if badge uses glyph
     */
    public boolean isGlyph() {
        return isGlyph;
    }

    /**
     * Returns the text for the badge.
     * Note that if {@link #isGlyph} is true, the text is a glyph ID, otherwise
     * the text is displayed verbatim in the badge.
     *
     * @return text for badge
     */
    public String text() {
        return text;
    }

    /**
     * Returns the message associated with the badge.
     *
     * @return associated message
     */
    public String message() {
        return message;
    }

    private static String nonNull(String s) {
        return s == null ? EMPTY : s;
    }

    /**
     * Returns an arbitrary text badge, with default status.
     *
     * @param txt the text
     * @return node badge to display text
     */
    public static NodeBadge text(String txt) {
        // TODO: consider length constraint on txt (3 chars?)
        return new NodeBadge(Status.INFO, false, nonNull(txt), null);
    }

    /**
     * Returns a glyph badge, with default status.
     *
     * @param gid the glyph ID
     * @return node badge to display glyph
     */
    public static NodeBadge glyph(String gid) {
        return new NodeBadge(Status.INFO, true, nonNull(gid), null);
    }

    /**
     * Returns a numeric badge, with default status.
     *
     * @param n the number
     * @return node badge to display a number
     */
    public static NodeBadge number(int n) {
        // TODO: consider constraints, e.g. 1 <= n <= 999
        return new NodeBadge(Status.INFO, false, Integer.toString(n), null);
    }

    /**
     * Returns an arbitrary text badge, with the given status.
     *
     * @param s the status
     * @param txt the text
     * @return node badge to display text
     */
    public static NodeBadge text(Status s, String txt) {
        // TODO: consider length constraint on txt (3 chars?)
        return new NodeBadge(s, false, nonNull(txt), null);
    }

    /**
     * Returns a glyph badge, with the given status.
     *
     * @param s the status
     * @param gid the glyph ID
     * @return node badge to display glyph
     */
    public static NodeBadge glyph(Status s, String gid) {
        return new NodeBadge(s, true, nonNull(gid), null);
    }


    /**
     * Returns a numeric badge, with the given status and optional message.
     *
     * @param s the status
     * @param n the number
     * @return node badge to display a number
     */
    public static NodeBadge number(Status s, int n) {
        // TODO: consider constraints, e.g. 1 <= n <= 999
        return new NodeBadge(s, false, Integer.toString(n), null);
    }

    /**
     * Returns an arbitrary text badge, with the given status and optional
     * message.
     *
     * @param s the status
     * @param txt the text
     * @param msg the optional message
     * @return node badge to display text
     */
    public static NodeBadge text(Status s, String txt, String msg) {
        // TODO: consider length constraint on txt (3 chars?)
        return new NodeBadge(s, false, nonNull(txt), msg);
    }

    /**
     * Returns a glyph badge, with the given status and optional message.
     *
     * @param s the status
     * @param gid the glyph ID
     * @param msg the optional message
     * @return node badge to display glyph
     */
    public static NodeBadge glyph(Status s, String gid, String msg) {
        return new NodeBadge(s, true, nonNull(gid), msg);
    }


    /**
     * Returns a numeric badge, with the given status and optional message.
     *
     * @param s the status
     * @param n the number
     * @param msg the optional message
     * @return node badge to display a number
     */
    public static NodeBadge number(Status s, int n, String msg) {
        // TODO: consider constraints, e.g. 1 <= n <= 999
        return new NodeBadge(s, false, Integer.toString(n), msg);
    }

}
