/*
 * Copyright (C) 2009-2017 Alistair Neil <info@dazzleships.net>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package client;

import java.text.DecimalFormat;

/**
 *
 * @author Alistair Neil <info@dazzleships.net>
 */
public class NodeItem extends Object implements Cloneable {

    public static final int TYPE_EXIT = 1;
    public static final int TYPE_GUARD = 2;
    public static final int TESTSTATUS_UNKNOWN = 0;
    public static final int TESTSTATUS_PASSED = 1;
    public static final int TESTSTATUS_FAILED = 2;
    private int type;
    private boolean exitFavourite;
    private boolean guardEnabled;
    private boolean httpSupported;
    private String stable;
    private String countrycode;
    private String countryname;
    private String nickname;
    private String finger;
    private String ipaddress;
    private String testingmess;
    private String circuithops;
    private int teststatus;
    private float bandwidth;
    private int streams;
    private long latency;
    private long testlatency;

    public NodeItem() {
        this.type = 0;
        this.exitFavourite = false;
        this.guardEnabled = false;
        this.httpSupported = false;
        this.countrycode = null;
        this.latency = 9999;
        this.testlatency = this.latency;
        this.bandwidth = 0;
        this.streams = 0;
        this.countrycode = "";
        this.countryname = "";
        this.stable = "";
        this.testingmess = "";
        this.ipaddress = "";
        this.finger = "";
        this.nickname = "";
        this.teststatus = TESTSTATUS_UNKNOWN;
    }

    /**
     * Set Node type
     *
     * @param mask
     */
    public final void setType(int mask) {
        this.type |= mask;
    }

    /**
     * Clear node type
     */
    public final void clearType() {
        this.type = 0;
    }

    public boolean isNonUnique() {
        return (nickname.contains("Default")
                || nickname.contains("default")
                || nickname.contains("Unnamed"));
    }

    /**
     * Is exit node
     *
     * @return true if an exit node
     */
    public final boolean isExit() {
        return (type & TYPE_EXIT) != 0;
    }

    public boolean isHttpSupported() {
        return httpSupported;
    }

    public void setHttpSupported(boolean supported) {
        httpSupported = supported;
    }

    /**
     * Is Guard node
     *
     * @return true if guard node
     */
    public final boolean isGuard() {
        return (type & TYPE_GUARD) != 0;
    }

    /**
     * Set circuit hops
     *
     * @param hops
     */
    public final void setCircuitHops(String hops) {
        circuithops = hops;
    }

    /**
     * Get circuit hops
     *
     * @return Circuit hops as String
     */
    public final String getCircuitHops() {
        return circuithops;
    }

    /**
     * Set Nodeitem testing status message
     *
     * @param text
     */
    public final void setTestingMessage(String text) {
        this.testingmess = text;
    }

    /**
     * Set testing status flag
     *
     * @param status
     */
    public final void setTestStatus(int status) {
        teststatus = status;
    }

    /**
     * Get testing status flag
     *
     * @return test status
     */
    public final int getTestStatus() {
        return teststatus;
    }

    /**
     * Get Node item status
     *
     * @return Nodeitem testing status message as string
     */
    public final String getTestingMessage() {
        return testingmess;
    }

    /**
     * Set Nodeitem latency value in ms
     *
     * @param latency
     */
    public final void setLatency(long latency) {
        this.latency = latency;
    }

    /**
     * Get Nodeitem latency in ms
     *
     * @return Latency value in ms
     */
    public final long getLatency() {
        return latency;
    }

    /**
     * Set Nodeitem test latency value in ms
     *
     * @param latency
     */
    public final void setTestLatency(long latency) {
        this.testlatency = latency;
    }

    /**
     * Get Nodeitem test latency in ms
     *
     * @return Latency value in ms
     */
    public final long getTestLatency() {
        return testlatency;
    }

    /**
     * Set exit enabled status of Nodeitem
     *
     * @param enabled
     */
    public final void setFavouriteEnabled(boolean enabled) {
        this.exitFavourite = enabled;
    }

    /**
     * Get exit enabled status of Nodeitem
     *
     * @return true if enabled
     */
    public final boolean isFavourite() {
        return exitFavourite;
    }

    /**
     * Set guard enabled status of Nodeitem
     *
     * @param enabled
     */
    public final void setGuardEnabled(boolean enabled) {
        this.guardEnabled = enabled;
    }

    /**
     * Get guard enabled status of Nodeitem
     *
     * @return true if enabled
     */
    public final boolean isGuardEnabled() {
        return guardEnabled;
    }

    /**
     * Set Nodeitem stability yes/no/unknown
     *
     * @param stability
     */
    public final void setStable(String stability) {
        this.stable = stability;
    }

    /**
     * Get Nodeitem stability
     *
     * @return Stability
     */
    public final String getStability() {
        return stable;
    }

    /**
     * Set Nodeitem with its two letter country code abbreviation
     *
     * @param abrv
     */
    public final void setCountryCode(String abrv) {
        countrycode = abrv;
    }

    /**
     * Get nodeitem two letter country code abbreviation
     *
     * @return Country code as string
     */
    public final String getCountryCode() {
        return countrycode;
    }

    /**
     * Set Nodeitem with its full country name
     *
     * @param name
     */
    public final void setCountryName(String name) {
        countryname = name;
    }

    /**
     * Get nodeitem full country name
     *
     * @return Country name as string
     */
    public final String getCountryName() {
        return countryname;
    }

    /**
     * Set nodeitem name
     *
     * @param name
     */
    public final void setNickName(String name) {
        nickname = name;
    }

    /**
     * Get nodeitem unique name
     *
     * @return Node name as string
     */
    public final String getNickName() {
        return nickname;
    }

    /**
     * Set node item bandwidth
     *
     * @param bw
     */
    public final void setBandwidth(float bw) {
        bandwidth = bw;
    }

    /**
     * Get nodeitem bandwith
     *
     * @return Bandwidth as long, in kb/s
     */
    public final float getBandwidth() {
        Float result;
        try {
            DecimalFormat df = new DecimalFormat("#0.##");
            result = Float.parseFloat(df.format(bandwidth).replace(",", "."));
        } catch (Exception ex) {
            result = (float) 0;
        }
        return result;
    }

    /**
     * Set nodeitem number of streams
     *
     * @param streams
     */
    public final void setStreams(int streams) {
        this.streams = streams;
    }

    /**
     * Get nodeitems active streams
     *
     * @return Number of active streams as int
     */
    public final int getStreams() {
        return streams;
    }

    /**
     * Set nodeitem fingerprint
     *
     * @param fp
     */
    public final void setFingerprint(String fp) {
        finger = fp;
    }

    /**
     * Get nodeitems fingerprint
     *
     * @return Tor node fingerprint as string
     */
    public final String getFingerprint() {
        return finger;
    }

    /**
     * Set nodeitem ip address
     *
     * @param ip
     */
    public final void setIPAddress(String ip) {
        ipaddress = ip;
    }

    /**
     * Get nodeitem ip address
     *
     * @return IP address as a string
     */
    public final String getIPAddress() {
        return ipaddress;
    }

    @Override
    public NodeItem clone() {
        try {
            return (NodeItem) super.clone();
        } catch (CloneNotSupportedException ex) {
            return null;
        }
    }

}
