package org.kne.cloud.network.ipv6;

import java.util.Objects;
import java.util.function.Supplier;

public class RouteItem implements Comparable<RouteItem>,Cloneable{
	private IPv6AddressGroup destination;
	private IPv6Address nexthop;
	private IPv6NetworkLink destlink;
	private String proto;
	private int pre;
	private long cost;
	private String flag;
	private Supplier<Long> costSupplier;
	private boolean isLoopback;
	public String getFlag() {
		return flag;
	}
	@Override
	public int hashCode() {
		return Objects.hash(cost, destination, destlink, flag, nexthop, pre, proto);
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		RouteItem other = (RouteItem) obj;
		return cost == other.cost && Objects.equals(destination, other.destination)
			 && Objects.equals(flag, other.flag)
				 && pre == other.pre && Objects.equals(proto, other.proto);
	}
	public RouteItem(IPv6AddressGroup destination, IPv6Address nexthop, IPv6NetworkLink destlink, String proto, int pre,
			long cost,String flag,boolean isLoopback) {
		super();
		this.destination = destination;
		this.nexthop = nexthop;
		this.destlink = destlink;
		this.proto = proto;
		this.pre = pre;
		this.cost = cost;
		this.flag=flag;
		this.isLoopback=isLoopback;
	}
	public RouteItem(IPv6AddressGroup destination, IPv6Address nexthop, IPv6NetworkLink destlink, String proto, int pre,
			long cost,Supplier<Long> costSupplier,String flag,boolean isLoopback) {
		super();
		this.destination = destination;
		this.nexthop = nexthop;
		this.destlink = destlink;
		this.proto = proto;
		this.pre = pre;
		this.cost = cost;
		this.costSupplier=costSupplier;
		this.flag=flag;
		this.isLoopback=isLoopback;
	}
	public IPv6AddressGroup getDestination() {
		return destination;
	}
	public IPv6Address getNexthop() {
		return nexthop;
	}
	public IPv6NetworkLink getDestlink() {
		return destlink;
	}
	public String getProto() {
		return proto;
	}
	public int getPre() {
		return pre;
	}
	public boolean isLoopback() {
		return isLoopback;
	}
	@Override
	public String toString() {
		return getDestination()+"\t"+getProto()+"\t"+getPre()+"\t"+getCost()+"\t"+getFlag()+"\t"+getNexthop()+"\t"+getDestlink().getName();
	}
	public long getCost() {
		return cost;
	}
	/*public boolean checkMatch(IPv6Address ia) {
		return destination.checkMatch(ia);
	}
	public boolean checkMatch(byte[] ia) {
		return destination.checkMatch(ia);
	}*/
	
	@Override
	public int compareTo(RouteItem o) {
		int v1=destination.compareTo(o.destination);
		if(v1!=0)
		return v1;
		int v2=Integer.compare(pre, o.pre);
		if(v2!=0)
			return v2;
		int v3=Long.compare(cost, o.cost);
		return v3;
	}
	public Supplier<Long> getCostSupplier() {
		return costSupplier;
	}
	@Override
	public Object clone()  {
		try {
			RouteItem ri=(RouteItem) super.clone();
			return ri;
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
			return null;
		}
	}
	//在排序前调用，计算cost
	public void updateCost() {
		if(costSupplier!=null) {
			cost=costSupplier.get();
		}
	}
	public boolean ECMPequals(RouteItem prevr) {
		return prevr.getDestination().getPrefixLength()==getDestination().getPrefixLength()&&prevr.getPre()==getPre();
			
	}
	
}
