package org.verapdf.model.impl.pb.cos;

import org.apache.log4j.Logger;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSDocument;
import org.apache.pdfbox.cos.COSName;
import org.verapdf.model.baselayer.Object;
import org.verapdf.model.coslayer.CosDocument;
import org.verapdf.model.coslayer.CosIndirect;
import org.verapdf.model.coslayer.CosTrailer;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Evgeniy Muravitskiy on 5/4/15.
 * <p>
 *     Low-level PDF Document object
 * </p>
 */
public class PBCosDocument extends PBCosObject implements CosDocument {

    private final static Logger logger = Logger.getLogger(PBCosDocument.class);

    public final static String TRAILER = "trailer";
    public final static String XREF = "xref";
    public final static String INDIRECT_OBJECTS = "indirectObjects";
    public final static String DOCUMENT = "document";

    private Integer sizeOfDocument = -1;

    public PBCosDocument(COSDocument baseObject) {
        super(baseObject);
        setType("CosDocument");
    }

    /**  Number of indirect objects in the document
     */
    @Override
    public Long getnrIndirects() {
        return (long) ((COSDocument) baseObject).getObjects().size();
    }

    /**  Size of the byte sequence representing the document
     */
    @Override
    public Long getsize() {
        return Long.valueOf(sizeOfDocument);
    }

    /**  true if the second line of the document is a comment with at least 4 symbols in the code range 128-255 as required by PDF/A standard
     */
    @Override
    public Boolean getbinaryHeaderComplyPDFA() {
        return !((COSDocument) baseObject).getNonValidHeader();
    }

    /** true if first line of document complies PDF/A standard
     */
    @Override
    public Boolean getpdfHeaderCompliesPDFA() {
        return !(((COSDocument) baseObject).getNonValidCommentContent() ||
                 ((COSDocument) baseObject).getNonValidCommentLength() ||
                 ((COSDocument) baseObject).getNonValidCommentStart());
    }

    /** true if catalog contain OCProperties key
     */
    @Override
    public Boolean getisOptionalContentPresent() {
        try {
            COSDictionary root = (COSDictionary) ((COSDocument) baseObject).getCatalog().getObject();
            return root.getItem(COSName.OCPROPERTIES) != null;
        } catch (IOException e) {
            return false;
        }
    }

    /** EOF must complies PDF/A standard
     */
    public Boolean geteofCompliesPDFA() {
        return ((COSDocument) baseObject).getEofComplyPDFA();
    }

    @Override
    public List<? extends org.verapdf.model.baselayer.Object> getLinkedObjects(String link) {
        List<? extends org.verapdf.model.baselayer.Object> list;

        switch (link) {
            case TRAILER:
                list = this.getTrailer();
                break;
            case INDIRECT_OBJECTS:
                list = this.getIndirectObjects();
                break;
            case DOCUMENT:
                list = this.getDocument();
                break;
            case XREF:
                list = this.getXRef();
                break;
            default:
                list = super.getLinkedObjects(link);
        }

        return list;
    }

    /**  trailer dictionary
     */
    private List<CosTrailer> getTrailer() {
        List<CosTrailer> trailer = new ArrayList<>();
        trailer.add(new PBCosTrailer(((COSDocument) baseObject).getTrailer()));
        return trailer;
    }

    /**  all indirect objects referred from the xref table
     */
    private List<CosIndirect> getIndirectObjects() {
        List<CosIndirect> indirects = new ArrayList<>();
        for (COSBase object : ((COSDocument) baseObject).getObjects()) {
            indirects.add(new PBCosIndirect(object));
        }
        return indirects;
    }

    /**  link to the high-level PDF Document structure
     */
    // TODO : add support of this feature
    private List<Object> getDocument() {
        logger.warn("Trying get PDDocument from CosDocument.\r\n" +
                "Current feature not supported yet. Method always return null.");
        return null;
    }

    /** link to cross reference table properties
     */
    // TODO : add support of this feature
    private List<? extends Object> getXRef() {
        logger.warn("Xref not supported yes. return null");
        return null;
    }
}

@@ -1685,32 +1685,33 @@
 rComplyPDFA() %7B%0A
+%0A
         return !
@@ -1712,16 +1712,17 @@
 turn !((
+(
 COSDocum
@@ -1753,15 +1753,169 @@
 alid
-Header(
+CommentContent() %7C%7C%0A                ((COSDocument) baseObject).getNonValidCommentLength() %7C%7C%0A                ((COSDocument) baseObject).getNonValidCommentStart()
 );%0A 
@@ -2063,33 +2063,32 @@
       return !((
-(
 COSDocument) bas
@@ -2111,171 +2111,15 @@
 alid
-CommentContent() %7C%7C%0A                 ((COSDocument) baseObject).getNonValidCommentLength() %7C%7C%0A                 ((COSDocument) baseObject).getNonValidCommentStart()
+Header(
 );%0A 

Replace implementation of pdf and binary header methods