package dk.statsbiblioteket.doms.transformers.shardmigrator;

import dk.statsbiblioteket.doms.central.CentralWebservice;
import dk.statsbiblioteket.doms.central.CentralWebserviceService;
import dk.statsbiblioteket.doms.central.InvalidCredentialsException;
import dk.statsbiblioteket.doms.central.InvalidResourceException;
import dk.statsbiblioteket.doms.central.MethodFailedException;
import dk.statsbiblioteket.doms.central.Relation;
import dk.statsbiblioteket.doms.transformers.common.ObjectHandler;
import dk.statsbiblioteket.doms.transformers.common.PropertyBasedDomsConfig;
import dk.statsbiblioteket.doms.transformers.shardmigrator.programStructure.autogenerated.MissingEnd;
import dk.statsbiblioteket.doms.transformers.shardmigrator.programStructure.autogenerated.MissingStart;
import dk.statsbiblioteket.doms.transformers.shardmigrator.programStructure.autogenerated.ProgramStructure;
import dk.statsbiblioteket.doms.transformers.shardmigrator.programStructure.autogenerated.ProgramStructure.Holes;
import dk.statsbiblioteket.doms.transformers.shardmigrator.programStructure.autogenerated.ProgramStructure.Overlaps;
import dk.statsbiblioteket.doms.transformers.shardmigrator.shardmetadata.autogenerated.Hole;
import dk.statsbiblioteket.doms.transformers.shardmigrator.shardmetadata.autogenerated.Overlap;
import dk.statsbiblioteket.doms.transformers.shardmigrator.shardmetadata.autogenerated.ShardStructure;

import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import java.net.URL;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Use DOMS to handle object transformation for shard removal for a UUID.
 */
public class DomsShardMigratorObjectHandler implements ObjectHandler {

    private final PropertyBasedDomsConfig config;
    private CentralWebservice webservice;

    /**
     * Initialise object handler.
     * @param config Configuration.
     */
    public DomsShardMigratorObjectHandler(PropertyBasedDomsConfig config, CentralWebservice webservice) {
        this.webservice = webservice;
        this.config = config;
    }

    @Override
    public void transform(String uuid)
            throws InvalidCredentialsException, MethodFailedException, InvalidResourceException {
        List<Relation> shardRelations = webservice.getNamedRelations(uuid, "http://doms.statsbiblioteket.dk/relations/default/0/1/#hasShard");
        if (shardRelations.isEmpty()) {
            // nothing to do
        }
        String shardUuid = shardRelations.get(0).getObject();
        String shardMetadata = webservice.getDatastreamContents(shardUuid, "SHARD_METADATA");
        List<Relation> fileRelations = webservice.getNamedRelations(shardUuid,
                                                                    "http://doms.statsbiblioteket.dk/relations/default/0/1/#consistsOf");

        // TODO Move shardStructure to program object and replace file references with UUID references
        // TODO Add file relations to program object
        // TODO Make sure pbcore metadata contains correct info (resolvable channel mappings, real time codes)

        // TODO Update file metadata (Consider: Should files be updated in separate workflow? What happens to unreferenced files. Eek. Also, we still need to register unregistered files anyway, so we need to run through all files anyway.)
        throw new UnsupportedOperationException("Not implemented yet");
    }
    

    private ProgramStructure convertShardStructure(ShardStructure shardStructure)   
            throws InvalidCredentialsException, InvalidResourceException, MethodFailedException {
        ProgramStructure programStructure = new ProgramStructure();
        if(shardStructure.getMissingEnd() != null) {
            MissingEnd missingEnd = new MissingEnd();
            missingEnd.setMissingSeconds(shardStructure.getMissingEnd().getMissingSeconds());
        }
        if(shardStructure.getMissingStart() != null) {
            MissingStart missingStart = new MissingStart();
            missingStart.setMissingSeconds(shardStructure.getMissingStart().getMissingSeconds());
        }
        if(!shardStructure.getHoles().getHole().isEmpty()) {
            Holes holes = new Holes();
            Iterator<Hole> it = shardStructure.getHoles().getHole().iterator();
            while(it.hasNext()) {
                Hole shardHole = it.next();
                dk.statsbiblioteket.doms.transformers.shardmigrator.programStructure.autogenerated.Hole programHole = 
                        new dk.statsbiblioteket.doms.transformers.shardmigrator.programStructure.autogenerated.Hole();
                programHole.setHoleLength(shardHole.getHoleLength());
                programHole.setFile1UUID(webservice.getFileObjectWithURL(shardHole.getFilePath1()));
                programHole.setFile2UUID(webservice.getFileObjectWithURL(shardHole.getFilePath2()));
                holes.getHole().add(programHole);
            }
            programStructure.setHoles(holes);
        }       
        if(!shardStructure.getOverlaps().getOverlap().isEmpty()) {
            Overlaps overlaps = new Overlaps();
            Iterator<Overlap> it = shardStructure.getOverlaps().getOverlap().iterator();
            while(it.hasNext()) {
                Overlap shardOverlap = it.next();
                dk.statsbiblioteket.doms.transformers.shardmigrator.programStructure.autogenerated.Overlap programOverlap = 
                        new dk.statsbiblioteket.doms.transformers.shardmigrator.programStructure.autogenerated.Overlap();
                programOverlap.setOverlapLength(shardOverlap.getOverlapLength());
                programOverlap.setOverlapType(shardOverlap.getOverlapType());
                programOverlap.setFile1UUId(webservice.getFileObjectWithURL(shardOverlap.getFilePath1()));
                programOverlap.setFile2UUID(webservice.getFileObjectWithURL(shardOverlap.getFilePath2()));
                overlaps.getOverlap().add(programOverlap);
            }
            programStructure.setOverlaps(overlaps);
        }
        
        return programStructure;
    }
    
}

@@ -1398,27 +1398,201 @@
 ed.Shard
-Structure;%0A
+Metadata;%0Aimport dk.statsbiblioteket.doms.transformers.shardmigrator.shardmetadata.autogenerated.ShardStructure;%0A%0Aimport javax.xml.bind.JAXBContext;%0Aimport javax.xml.bind.JAXBException;
 %0Aimport 
@@ -1654,16 +1654,54 @@
 rovider;
+%0A%0Aimport java.io.ByteArrayInputStream;
 %0Aimport 
@@ -3048,16 +3048,442 @@
 sOf%22);%0A%0A
+        try %7B%0A            ShardMetadata shard = deserializeShardMetadata(shardMetadata);%0A            ProgramStructure programStructure;%0A            if(shard.getShardStructure() != null) %7B%0A                programStructure = convertShardStructure(shard.getShardStructure());    %0A            %7D%0A        %7D catch (JAXBException e) %7B%0A            // TODO Auto-generated catch block%0A            e.printStackTrace();%0A        %7D%0A        %0A
         
@@ -4064,17 +4064,16 @@
  %7D%0A    %0A
-%0A
     priv
@@ -4076,16 +4076,307 @@
 private 
+ShardMetadata deserializeShardMetadata(String shardMetadataString) throws JAXBException %7B%0A        return (ShardMetadata) JAXBContext.newInstance(ShardMetadata.class).createUnmarshaller().unmarshal(%0A                new ByteArrayInputStream(shardMetadataString.getBytes()));%0A    %7D%0A%0A    public 
 ProgramS

Add deserialiser for ShartMetadata objects