/*
 * Copyright 2017-present 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;

import com.google.common.base.Strings;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Represents a "node location" on a UI layout.
 */
public final class LayoutLocation {
    private static final double ZERO_THRESHOLD = Double.MIN_VALUE * 2.0;
    private static final String COMMA = ",";
    private static final String TILDE = "~";
    private static final String EMPTY = "";

    private static final String E_BAD_COMPACT = "Badly formatted compact form: ";
    private static final String E_EMPTY_ID = "id must be non-empty";
    private static final String E_BAD_DOUBLE = "unparsable double";


    /**
     * Designates the type of location; either geographic or logical grid.
     */
    public enum Type {
        GEO, GRID
    }

    private final String id;
    private final double latOrY;
    private final double longOrX;
    private final Type locType;

    private LayoutLocation(String id, Type locType, double latOrY, double longOrX) {
        this.id = id;
        this.latOrY = latOrY;
        this.longOrX = longOrX;
        this.locType = locType;
    }

    private boolean doubleIsZero(double value) {
        return value >= -ZERO_THRESHOLD && value <= ZERO_THRESHOLD;
    }

    /**
     * Returns true if the coordinates indicate the origin (0, 0) of the
     * coordinate system; false otherwise.
     *
     * @return true if geo-coordinates are set; false otherwise
     */
    public boolean isOrigin() {
        return doubleIsZero(latOrY) && doubleIsZero(longOrX);
    }

    /**
     * Returns the identifier associated with this location.
     *
     * @return the identifier
     */
    public String id() {
        return id;
    }

    /**
     * Returns the location type (geo or grid), which indicates how the data
     * is to be interpreted.
     *
     * @return location type
     */
    public Type locType() {
        return locType;
    }

    /**
     * Returns the latitude (geo) or y-coord (grid) data value.
     *
     * @return geo latitude or grid y-coord
     */
    public double latOrY() {
        return latOrY;
    }

    /**
     * Returns the longitude (geo) or x-coord (grid) data value.
     *
     * @return geo longitude or grid x-coord
     */
    public double longOrX() {
        return longOrX;
    }

    @Override
    public String toString() {
        return toStringHelper(this)
                .add("id", id)
                .add("loc-type", locType)
                .add("lat/Y", latOrY)
                .add("long/X", longOrX)
                .toString();
    }

    /**
     * Produces a compact string representation of this instance.
     *
     * @return compact string rep
     */
    public String toCompactListString() {
        return id + COMMA + locType + COMMA + latOrY + COMMA + longOrX;
    }

    /**
     * Produces a layout location instance from a compact string representation.
     *
     * @param s the compact string
     * @return a corresponding instance
     */
    public static LayoutLocation fromCompactString(String s) {
        String[] tokens = s.split(COMMA);
        if (tokens.length != 4) {
            throw new IllegalArgumentException(E_BAD_COMPACT + s);
        }
        String id = tokens[0];
        String type = tokens[1];
        String latY = tokens[2];
        String longX = tokens[3];

        if (Strings.isNullOrEmpty(id)) {
            throw new IllegalArgumentException(E_BAD_COMPACT + E_EMPTY_ID);
        }

        double latOrY;
        double longOrX;
        try {
            latOrY = Double.parseDouble(latY);
            longOrX = Double.parseDouble(longX);
        } catch (NumberFormatException nfe) {
            throw new IllegalArgumentException(E_BAD_COMPACT + E_BAD_DOUBLE);
        }

        return LayoutLocation.layoutLocation(id, type, latOrY, longOrX);
    }

    /**
     * Produces a compact encoding of a list of layout locations.
     *
     * @param locs array of layout location instances
     * @return string encoding
     */
    public static String toCompactListString(LayoutLocation... locs) {
        if (locs == null || locs.length == 0) {
            return EMPTY;
        }
        List<LayoutLocation> lls = Arrays.asList(locs);
        return toCompactListString(lls);
    }

    /**
     * Produces a compact encoding of a list of layout locations.
     *
     * @param locs list of layout location instances
     * @return string encoding
     */
    public static String toCompactListString(List<LayoutLocation> locs) {
        // note: locs may be empty
        if (locs == null || locs.isEmpty()) {
            return EMPTY;
        }

        StringBuilder sb = new StringBuilder();
        for (LayoutLocation ll : locs) {
            sb.append(ll.toCompactListString()).append(TILDE);
        }
        final int len = sb.length();
        sb.replace(len - 1, len, "");
        return sb.toString();
    }

    /**
     * Returns a list of layout locations from a compact string representation.
     *
     * @param compactList string representation
     * @return corresponding list of layout locations
     */
    public static List<LayoutLocation> fromCompactListString(String compactList) {
        List<LayoutLocation> locs = new ArrayList<>();
        if (!Strings.isNullOrEmpty(compactList)) {
            String[] items = compactList.split(TILDE);
            for (String s : items) {
                locs.add(fromCompactString(s));
            }
        }
        return locs;
    }


    /**
     * Creates an instance of a layout location.
     *
     * @param id      an identifier for the item at this location
     * @param locType the location type
     * @param latOrY  geo latitude / grid y-coord
     * @param longOrX geo longitude / grid x-coord
     * @return layout location instance
     */
    public static LayoutLocation layoutLocation(String id, Type locType,
                                                double latOrY, double longOrX) {
        checkNotNull(id, "must supply an identifier");
        checkNotNull(locType, "must declare location type");
        return new LayoutLocation(id, locType, latOrY, longOrX);
    }

    /**
     * Creates an instance of a layout location.
     *
     * @param id      an identifier for the item at this location
     * @param locType the location type ("geo" or "grid")
     * @param latOrY  geo latitude / grid y-coord
     * @param longOrX geo longitude / grid x-coord
     * @return layout location instance
     * @throws IllegalArgumentException if the type is not "geo" or "grid"
     */
    public static LayoutLocation layoutLocation(String id, String locType,
                                                double latOrY, double longOrX) {
        Type t = Type.valueOf(locType.toUpperCase());
        return new LayoutLocation(id, t, latOrY, longOrX);
    }
}
