package ru.yandex.webmaster3.storage.originaltext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Required;
import ru.yandex.webmaster3.core.data.WebmasterHostId;

import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.Arrays;

/**
 * @author avhaliullin
 */
public class DelegatingOriginalTextService implements OriginalTextService {
    private static final Logger log = LoggerFactory.getLogger(DelegatingOriginalTextService.class);

    private DirectOriginalTextService directOriginalTextService;
    private ProxyOriginalTextService proxyOriginalTextService;

    private OriginalTextService delegate;
    private String directOriginalsAddress;

    public void init() {
        try {
            URL directUrl = new URL(directOriginalsAddress);
            InetAddress[] addresses = InetAddress.getAllByName(directUrl.getHost());
            boolean originalsHaveIpv6 = Arrays.stream(addresses).anyMatch(addr -> addr instanceof Inet6Address);
            if (!originalsHaveIpv6) {
                NetworkInterface defaultIface = NetworkInterface.getByName("eth0");
                if (defaultIface == null) {
                    log.warn("Failed to check for ipv4 support - interface eth0 not found");
                } else {
                    if (defaultIface.getInterfaceAddresses().stream().noneMatch(address -> address.getAddress() instanceof Inet4Address)) {
                        delegate = proxyOriginalTextService;
                        log.info("No ipv4 on eth0 - using proxy for originals service requests");
                    }
                }
            }
        } catch (SocketException | MalformedURLException | UnknownHostException e) {
            log.error("Failed to check for ipv4 support", e);
        }
        if (delegate == null) {
            log.info("Using direct originals service");
            delegate = directOriginalTextService;
        }
    }

    @Override
    public OriginalsResponse listTexts(WebmasterHostId hostId, int offset, int limit) {
        return delegate.listTexts(hostId, offset, limit);
    }

    @Override
    public OriginalsResponse addText(WebmasterHostId hostId, String text) {
        return delegate.addText(hostId, text);
    }

    @Override
    public OriginalTextLimits getLimits(WebmasterHostId hostId) {
        return delegate.getLimits(hostId);
    }

    @Override
    public void deleteText(WebmasterHostId hostId, String textId) {
        delegate.deleteText(hostId, textId);
    }

    @Required
    public void setDirectOriginalTextService(DirectOriginalTextService directOriginalTextService) {
        this.directOriginalTextService = directOriginalTextService;
    }

    @Required
    public void setProxyOriginalTextService(ProxyOriginalTextService proxyOriginalTextService) {
        this.proxyOriginalTextService = proxyOriginalTextService;
    }

    @Required
    public void setDirectOriginalsAddress(String directOriginalsAddress) {
        this.directOriginalsAddress = directOriginalsAddress;
    }
}
