/*
 * This file is part of the DITA Open Toolkit project.
 *
 * Copyright 2017 Jarno Elovirta
 *
 * See the accompanying LICENSE file for applicable license.
 */

package org.dita.dost.writer;

import com.google.common.annotations.VisibleForTesting;
import org.dita.dost.util.Job;
import org.dita.dost.util.URLUtils;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

import java.net.URI;

import static org.dita.dost.util.Constants.*;
import static org.dita.dost.util.URLUtils.setFragment;
import static org.dita.dost.util.URLUtils.stripFragment;
import static org.dita.dost.util.URLUtils.toURI;
import static org.dita.dost.util.XMLUtils.addOrSetAttribute;

public class LinkFilter extends AbstractXMLFilter {

    private URI destFile;
    private URI base;

    @Override
    public void startElement(final String uri, final String localName, final String qName, final Attributes atts)
            throws SAXException {
        Attributes res = atts;

        if (hasLocalDitaLink(atts)) {
            final AttributesImpl resAtts = new AttributesImpl(atts);
            int i = atts.getIndex(ATTRIBUTE_NAME_IMAGEREF);
            if (i == -1) {
                i = atts.getIndex(ATTRIBUTE_NAME_HREF);
            }
            if (i == -1) {
                i = atts.getIndex(ATTRIBUTE_NAME_DATA);
            }
            if (i != -1) {
                final URI resHref = getHref(toURI(atts.getValue(i)));
                addOrSetAttribute(resAtts, atts.getQName(i), resHref.toString());
                res = resAtts;
            }
        }

        getContentHandler().startElement(uri, localName, qName, res);
    }

    private boolean hasLocalDitaLink(final Attributes atts) {
        final boolean hasHref = atts.getIndex(ATTRIBUTE_NAME_HREF) != -1;
        final boolean notExternal = !ATTR_SCOPE_VALUE_EXTERNAL.equals(atts.getValue(ATTRIBUTE_NAME_SCOPE));
        if (hasHref && notExternal) {
            return true;
        }
        final URI data = toURI(atts.getValue(ATTRIBUTE_NAME_DATA));
        if (data != null && !data.isAbsolute()) {
            return true;
        }
        final URI imageref = toURI(atts.getValue(ATTRIBUTE_NAME_IMAGEREF));
        if (imageref != null && !imageref.isAbsolute()) {
            return true;
        }
        return false;
    }

    @VisibleForTesting
    URI getHref(final URI href) {
        if (href.getFragment() != null && (href.getPath() == null || href.getPath().equals(""))) {
            return href;
        }
        final URI targetAbs = stripFragment(currentFile.resolve(href));
        final Job.FileInfo targetFileInfo = job.getFileInfo(targetAbs);
        if (targetFileInfo != null) {
            final URI rel = URLUtils.getRelativePath(base, targetFileInfo.result);
            final URI targetDestFile = job.tempDirURI.resolve(rel);
            final URI relTarget = URLUtils.getRelativePath(destFile, targetDestFile);
            return setFragment(relTarget, href.getFragment());
        } else {
            return href;
        }
    }

    public void setDestFile(final URI destFile) {
        this.destFile = destFile;
    }

    @Override
    public void setJob(final Job job) {
        super.setJob(job);
        base = job.getInputDir();
    }
}

@@ -274,16 +274,56 @@
 il.Job;%0A
+import org.dita.dost.util.Job.FileInfo;%0A
 import o
@@ -350,16 +350,16 @@
 LUtils;%0A
-
 import o
@@ -572,125 +572,9 @@
 ils.
-setFragment;%0Aimport static org.dita.dost.util.URLUtils.stripFragment;%0Aimport static org.dita.dost.util.URLUtils.toURI
+*
 ;%0Aim
@@ -686,16 +686,66 @@
 lter %7B%0A%0A
+    /**%0A     * Destination temporary file%0A     */%0A
     priv
@@ -2369,20 +2369,22 @@
 nal URI 
-href
+target
 ) %7B%0A    
@@ -2391,20 +2391,22 @@
     if (
-href
+target
 .getFrag
@@ -2424,20 +2424,22 @@
 ull && (
-href
+target
 .getPath
@@ -2452,20 +2452,22 @@
 null %7C%7C 
-href
+target
 .getPath
@@ -2495,36 +2495,38 @@
          return 
-href
+target
 ;%0A        %7D%0A    
@@ -2585,20 +2585,22 @@
 resolve(
-href
+target
 ));%0A    
@@ -2609,20 +2609,16 @@
   final 
-Job.
 FileInfo
@@ -2675,188 +2675,133 @@
     
-if (targetFileInfo != null) %7B%0A            final URI rel = URLUtils.getRelativePath(base, targetFileInfo.result);%0A            final URI targetDestFile = job.tempDirURI.resolve(rel);
+final FileInfo sourceFileInfo = job.getFileInfo(currentFile);%0A        if (targetFileInfo != null && sourceFileInfo != null) %7B
 %0A   
@@ -2860,32 +2860,52 @@
 ath(
-destFile, targetDestFile
+sourceFileInfo.result, targetFileInfo.result
 );%0A 
@@ -2945,20 +2945,22 @@
 Target, 
-href
+target
 .getFrag
@@ -3008,12 +3008,14 @@
 urn 
-href
+target
 ;%0A  
@@ -3075,24 +3075,62 @@
 destFile) %7B%0A
+        assert destFile.isAbsolute();%0A
         this

Fix preprocess link rewrite