package org.kne.cloud.network.scanner;

import java.math.BigInteger;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Objects;

public class InetAddressRange {
	private InetAddress begin;
	private InetAddress end;
	private String beginHost;
	private String endHost;
	public InetAddressRange (String host) throws UnknownHostException{
		this(host,host);
	}
	public InetAddressRange (String beginhost,String endhost) throws UnknownHostException {
		beginHost=beginhost;
		endHost=endhost;
		InetAddress begin=InetAddress.getByName(beginhost);
		InetAddress end=InetAddress.getByName(endhost);
		checkIPRange(begin, end);
		this.begin = begin;
		this.end = end;
	}
	public String getBeginHost() {
		if(beginHost!=null)
		return beginHost;
		return begin.getHostAddress();
	}
	public String getEndHost() {
		if(endHost!=null)
		return endHost;
		return end.getHostAddress();
	}
	public InetAddressRange(InetAddress address) {
		this(address,address);
	}
	public InetAddressRange(InetAddress begin, InetAddress end) {
		super();
		checkIPRange(begin, end);
		this.begin = begin;
		this.end = end;
	}
	private void checkIPRange(InetAddress begin, InetAddress end) throws IllegalArgumentException {
		if(begin instanceof Inet4Address&&end instanceof Inet6Address)
			throw new IllegalArgumentException("begin is IPv4 but end is IPv6");

		if(begin instanceof Inet6Address&&end instanceof Inet4Address)
			throw new IllegalArgumentException("begin is IPv6 but end is IPv4");
	}
	public InetAddress getBegin() {
		return begin;
	}
	@Override
	public int hashCode() {
		return Objects.hash(begin, end);
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		InetAddressRange other = (InetAddressRange) obj;
		return Objects.equals(begin, other.begin) && Objects.equals(end, other.end);
	}
	@Override
	public String toString() {
		return "InetAddressRange [begin=" + begin + ", end=" + end + "]";
	}
	public InetAddress getEnd() {
		return end;
	}
	public BigInteger getElementCount() {
		return new BigInteger(end.getAddress()).subtract(new BigInteger( begin.getAddress())).add(BigInteger.valueOf(1));
	}
}
