package io.lumify.imageMetadataExtractor;

import com.drew.imaging.ImageMetadataReader;
import com.drew.metadata.Metadata;
import io.lumify.core.ingest.graphProperty.GraphPropertyWorkData;
import io.lumify.core.ingest.graphProperty.GraphPropertyWorker;
import io.lumify.core.ingest.graphProperty.GraphPropertyWorkerPrepareData;
import io.lumify.core.model.properties.LumifyProperties;
import io.lumify.core.util.LumifyLogger;
import io.lumify.core.util.LumifyLoggerFactory;
import io.lumify.imageMetadataHelper.*;
import io.lumify.storm.MediaPropertyConfiguration;
import io.lumify.storm.util.FileSizeUtil;
import org.securegraph.Element;
import org.securegraph.Property;
import org.securegraph.Vertex;
import org.securegraph.mutation.ExistingElementMutation;

import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


public class ImageMetadataGraphPropertyWorker extends GraphPropertyWorker {
    private static final LumifyLogger LOGGER = LumifyLoggerFactory.getLogger(ImageMetadataGraphPropertyWorker.class);
    private static final String MULTI_VALUE_KEY = ImageMetadataGraphPropertyWorker.class.getName();
    private MediaPropertyConfiguration config = new MediaPropertyConfiguration();

    @Override
    public boolean isLocalFileRequired() {
        return true;
    }

    @Override
    public void prepare(GraphPropertyWorkerPrepareData workerPrepareData) throws Exception {
        super.prepare(workerPrepareData);
        getConfiguration().setConfigurables(config, MediaPropertyConfiguration.PROPERTY_NAME_PREFIX);
    }

    private void setProperty(String iri, Object value, ExistingElementMutation<Vertex> mutation, Map<String, Object> metadata, GraphPropertyWorkData data, List<String> properties) {
        if (iri != null && value != null) {
            mutation.addPropertyValue(MULTI_VALUE_KEY, iri, value, metadata, data.getVisibility());
            properties.add(iri);
        }
    }

    @Override
    public void execute(InputStream in, GraphPropertyWorkData data) throws Exception {
        Map<String, Object> metadata = data.createPropertyMetadata();
        ExistingElementMutation<Vertex> mutation = data.getElement().prepareMutation();
        List<String> properties = new ArrayList<String>();

        File imageFile = data.getLocalFile();
        if (imageFile != null) {
            Metadata imageMetadata = null;
            try {
                imageMetadata = ImageMetadataReader.readMetadata(imageFile);
            } catch (Exception e) {
                LOGGER.debug("Could not read metadata from imageFile.", e);
            }

            if (imageMetadata != null) {
                setProperty(config.getDateTakenIri(), DateExtractor.getDateDefault(imageMetadata), mutation, metadata, data, properties);
                setProperty(config.getDeviceMakeIri(), MakeExtractor.getMake(imageMetadata), mutation, metadata, data, properties);
                setProperty(config.getDeviceModelIri(), ModelExtractor.getModel(imageMetadata), mutation, metadata, data, properties);
                setProperty(config.getGeoLocationIri(), GeoPointExtractor.getGeoPoint(imageMetadata), mutation, metadata, data, properties);
                setProperty(config.getHeadingIri(), HeadingExtractor.getImageHeading(imageMetadata), mutation, metadata, data, properties);
                setProperty(config.getMetadataIri(), LeftoverMetadataExtractor.getAsJSON(imageMetadata).toString(), mutation, metadata, data, properties);
            }

            Integer width = imageMetadata != null ? DimensionsExtractor.getWidthViaMetadata(imageMetadata) : DimensionsExtractor.getWidthViaBufferedImage(imageFile);
            setProperty(config.getWidthIri(), width, mutation, metadata, data, properties);

            Integer height = imageMetadata != null ? DimensionsExtractor.getHeightViaMetadata(imageMetadata) : DimensionsExtractor.getHeightViaBufferedImage(imageFile);
            setProperty(config.getHeightIri(), height, mutation, metadata, data, properties);

            setProperty(config.getFileSizeIri(), FileSizeUtil.extractFileSize(imageFile), mutation, metadata, data, properties);
        }

        mutation.save(getAuthorizations());
        getGraph().flush();
        for (String propertyName : properties) {
            getWorkQueueRepository().pushGraphPropertyQueue(data.getElement(), MULTI_VALUE_KEY, propertyName);
        }
    }

    @Override
    public boolean isHandled(Element element, Property property) {
        if (property == null) {
            return false;
        }

        String mimeType = (String) property.getMetadata().get(LumifyProperties.MIME_TYPE.getPropertyName());
        if (mimeType != null && mimeType.startsWith("image")) {
            return true;
        }

        return false;
    }
}

@@ -4737,16 +4737,17 @@
 null && 
+(
 mimeType
@@ -4764,17 +4764,60 @@
 h(%22image
-%22
+/jpeg%22) %7C%7C mimeType.startsWith(%22image/tiff%22)
 )) %7B%0A   

check for valid mime types that the drew nokes library handles