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.Resource;
import be.iminds.ilabt.jfed.fedmon.webapi.service.json.Server;
import be.iminds.ilabt.jfed.lowlevel.api_wrapper.AggregateManagerWrapper;
import be.iminds.ilabt.jfed.rspec.model.Channel;
import be.iminds.ilabt.jfed.rspec.model.DiskImage;
import be.iminds.ilabt.jfed.rspec.model.HardwareType;
import be.iminds.ilabt.jfed.rspec.model.javafx_impl.FXRspecNode;
import be.iminds.ilabt.jfed.util.GeniUrn;
import javafx.util.StringConverter;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;

/**
 * User: twalcari
 * Date: 1/6/2015
 * Time: 13:52
 */
public class StringConverters {
    public static final StringConverter<DiskImage> DISK_IMAGE_STRING_CONVERTER = new StringConverter<DiskImage>() {
        @Override
        public String toString(DiskImage diskImage) {
            if (diskImage.getDescription() != null) {
                return diskImage.getDescription();
            } else if (diskImage.getOs() != null) {
                StringBuilder sb = new StringBuilder();
                sb.append(diskImage.getOs());
                if (diskImage.getVersion() != null) {
                    sb.append(" v");
                    sb.append(diskImage.getVersion());
                }
                return sb.toString();
            } else if (diskImage.getName() != null) {
                return diskImage.getName();
            } else {
                return String.format("<%s>", diskImage.getUrl());
            }
        }

        @Override
        public DiskImage fromString(String s) {
            return null;
        }
    };
    public static final StringConverter<AggregateManagerWrapper.ImageInfo> IMAGEINFO_STRING_CONVERTER =
            new StringConverter<AggregateManagerWrapper.ImageInfo>() {
                @Override
                public String toString(AggregateManagerWrapper.ImageInfo imageInfo) {
                    if (imageInfo.getUrn() != null) {
                        GeniUrn geniUrn = GeniUrn.parse(imageInfo.getUrn());

                        if (geniUrn != null) {
                            return geniUrn.getEncodedResourceName();
                        } else {
                            return imageInfo.getUrn();
                        }
                    } else {
                        return imageInfo.getUrl();
                    }
                }

                @Override
                public AggregateManagerWrapper.ImageInfo fromString(String s) {
                    return null;
                }
            };


    public static final StringConverter<Resource> RESOURCE_STRING_CONVERTER =
            new StringConverter<Resource>() {
                @Override
                public String toString(Resource resource) {
                    return resource.getServer().getName();
                }

                @Override
                public Resource fromString(String s) {
                    throw new UnsupportedOperationException();
                }

            };

    public static final StringConverter<Server> SERVER_STRING_CONVERTER =
            new StringConverter<Server>() {
                @Override
                public String toString(Server server) {
                    return server.getName();
                }

                @Override
                public Server fromString(String s) {
                    throw new UnsupportedOperationException();
                }

            };
    public static final StringConverter<FXRspecNode> ADV_RSPECNODE_CONVERTER = new StringConverter<FXRspecNode>() {
        @Override
        public String toString(FXRspecNode node) {
            if (node.getComponentName() != null)
                return node.getComponentName();
            else if (node.getComponentId() != null)
                return node.getComponentId().getEncodedResourceName();
            else
                return node.getClientId();
        }

        @Override
        public FXRspecNode fromString(String string) {
            throw new UnsupportedOperationException();
        }
    };
    public static final StringConverter<JFedGuiConfig.ComponentInfo> COMPONENT_INFO_CONVERTER = new StringConverter<JFedGuiConfig.ComponentInfo>() {
        @Override
        public String toString(JFedGuiConfig.ComponentInfo node) {
            if (node.getName() != null)
                return node.getName();
            else if (node.getUrn() != null)
                return node.getUrn().getEncodedResourceName();
            else
                return null;
        }

        @Override
        public JFedGuiConfig.ComponentInfo fromString(String string) {
            throw new UnsupportedOperationException();
        }
    };
    public static final StringConverter<GeniUrn> GENI_URN_CONVERTER = new StringConverter<GeniUrn>() {
        @Override
        public String toString(GeniUrn object) {
            return object.getEncodedResourceName();
        }

        @Override
        public GeniUrn fromString(String string) {
            throw new UnsupportedOperationException();
        }
    };
    public static final StringConverter<Channel> CHANNEL_CONVERTER = new StringConverter<Channel>() {
        @Override
        public String toString(Channel object) {
            if (object.getFrequency() != null) {
                return String.format("%s (%s)", object.getComponentName(), object.getFrequency());
            } else
                return object.getComponentName();
        }

        @Override
        public Channel fromString(String string) {
            throw new UnsupportedOperationException();
        }
    };
    public static final StringConverter<Instant> INSTANT_STRING_CONVERTER = new StringConverter<Instant>() {
        @Override
        public String toString(Instant date) {
            if (date != null) {
                return DateTimeUtils.DATE_HOUR_MINUTES_SECONDS_FORMATTER.format(LocalDateTime.ofInstant(date, ZoneId.systemDefault()));
            } else {
                return null;
            }
        }

        @Override
        public Instant fromString(String s) {
            return ZonedDateTime.parse(s, DateTimeUtils.DATE_HOUR_MINUTES_SECONDS_FORMATTER).toInstant();
        }
    };

    public static final StringConverter<HardwareType> HARDWARE_TYPE_CONVERTER = new StringConverter<HardwareType>() {
        @Override
        public String toString(HardwareType hardwareType) {
            return hardwareType.getName();
        }

        @Override
        public HardwareType fromString(String string) {
            throw new UnsupportedOperationException();
        }
    };

    private StringConverters() {
    }
}
