package be.iminds.ilabt.jfed.experimenter_gui.util;

import be.iminds.ilabt.jfed.experimenter_gui.config.JFedGuiConfig;
import be.iminds.ilabt.jfed.fedmon.webapi.service.json.ResourceClass;
import be.iminds.ilabt.jfed.fedmon.webapi.service.json.Server;
import be.iminds.ilabt.jfed.rspec.model.javafx_impl.FXRspecNode;
import javafx.scene.image.Image;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Nonnull;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * User: twalcari
 * Date: 11/8/13
 * Time: 2:40 PM
 */
@Singleton
public class ImageUtil {
    private static final Logger LOG = LoggerFactory.getLogger(ImageUtil.class);

    private final JFedGuiConfig config;


    @Inject
    public ImageUtil(JFedGuiConfig config) {
        this.config = config;
    }


    public Image getRspecNodeImage(FXRspecNode node, ImageSize imageSize) {
        return getRspecNodeImage(config, node, imageSize);
    }

    public static Image getRspecNodeImage(JFedGuiConfig config, FXRspecNode node, ImageSize imageSize) {
        ResourceClass resourceClass = config.getDefaultResourceClass();

        if (node.getResourceClassId() != null) {
            resourceClass = config.getResourceClass(node.getResourceClassId());
        }

        return getNodeDescriptionImage(resourceClass, imageSize);
    }

    private static final ImageSize[] FALLBACK_ORDER =
            {ImageSize.LARGE, ImageSize.MEDIUM, ImageSize.SMALL, ImageSize.X_SMALL};


    private static URL getNodeDescriptionImageURL(@Nonnull String imageId, ImageSize imageSize) {
        String urlString = String.format("/images/node_types/%d/%s.png",
                imageSize.getSize(), imageId);

        URL res = ImageUtil.class.getResource(urlString);

        return res;
    }

    private static URL getNodeDescriptionImageURL(ResourceClass resourceClass, ImageSize imageSize) {
        if (resourceClass.getImageId() == null) return null;

        URL res = getNodeDescriptionImageURL(resourceClass.getImageId(), imageSize);

        //Note: this prefers the locally stored image identified by imageId

        if (res == null) {
            //fall back to URN specified in ResourceClass

            if (resourceClass.getImageUrl() != null)
                try {
                    return new URL(resourceClass.getImageUrl());
                } catch (MalformedURLException e) {
                    LOG.error("Invalid URN in resourceClass "+resourceClass.getId()+": \""+resourceClass.getImageUrl()+"\"", e);
                    return null;
                }
        }

        return res;
    }

    public static Image getNodeDescriptionImage(ResourceClass resourceClass, ImageSize imageSize) {
        assert resourceClass != null;

        URL url = getNodeDescriptionImageURL(resourceClass, imageSize);

        int i = 0;
        while (url == null && i < FALLBACK_ORDER.length) {
            url = getNodeDescriptionImageURL(resourceClass, FALLBACK_ORDER[i]);
            i++;
        }

        if (url != null)
            return new Image(url.toExternalForm());
        else
            return null;
    }

    private static URL getTestbedImageURL(Server server, ImageSize imageSize) {
        if (server.getTestbed().getLogo() == null)
            return null;

        String urlString = String.format("/images/testbeds/%d/%s",
                imageSize.getSize(), server.getTestbed().getLogo());

        return ImageUtil.class.getResource(urlString);
    }

    public static Image getTestbedDescriptionImage(Server server, ImageSize imageSize) {
        if (server.getTestbed().getLogo() == null)
            return null;

        URL url = getTestbedImageURL(server, imageSize);

        int i = 0;
        while (url == null && i < FALLBACK_ORDER.length) {
            url = getTestbedImageURL(server, FALLBACK_ORDER[i]);
            i++;
        }

        if (url != null)
            return new Image(url.toExternalForm());
        else
            return null;
    }


}
