package be.iminds.ilabt.jfed.gts.model;

import javafx.collections.ObservableList;

import javax.annotation.Nonnull;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * User: twalcari
 * Date: 6/5/2015
 * Time: 15:56
 */
public interface GtsType {


    String getName();

    void setName(String name);

    String getDescription();

    void setDescription(String description);

    Map<String, ? extends GtsPort> getPorts();

    void setPorts(Map<String, ? extends GtsPort> ports);

    String getProviderId();

    void setProviderId(String providerId);

    GtsStatus getStatus();

    void setStatus(GtsStatus status);

    ObservableList<Adjacency> getAdjacencies();

    void setAdjacencies(List<Adjacency> adjacencies);

    void addPort(GtsPort port);

    /**
     * @return true when it is a type definition, false when it is a type instantiation.
     */
    boolean isDefinition();

    void setDefinition(boolean isDefinition);

    final class Adjacency implements GtsAdjacency{
        @Nonnull
        private PortId portId1;
        @Nonnull
        private PortId portId2;

        public Adjacency(@Nonnull PortId portId1, @Nonnull PortId portId2) {
            this.portId1 = portId1;
            this.portId2 = portId2;
        }

        @Override
        @Nonnull
        public PortId getPortId1() {
            return portId1;
        }

        @Override
        @Nonnull
        public PortId getPortId2() {
            return portId2;
        }

        public void setPortId1(@Nonnull PortId portId1) {
            this.portId1 = portId1;
        }

        public void setPortId2(@Nonnull PortId portId2) {
            this.portId2 = portId2;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            Adjacency adjacency = (Adjacency) o;

            if (!Objects.equals(portId1, adjacency.portId1)) return false;
            return Objects.equals(portId2, adjacency.portId2);

        }

        @Override
        public int hashCode() {
            int result = portId1.hashCode();
            result = 31 * result + portId2.hashCode();
            return result;
        }

        @Override
        public String toString() {
            return "Adjacency{" +
                    "portId1=" + portId1 +
                    ", portId2=" + portId2 +
                    '}';
        }
    }

    List<? extends GtsNode> getNodes();

    void addNode(GtsNode node);

    List<? extends GtsLink> getLinks();

    void addLink(GtsLink link);

    Map<String, String> getExtraProperties();

}
