/* ====================================================================
   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
==================================================================== */

package org.apache.poi.xwpf.usermodel;

import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.ooxml.POIXMLRelation;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.Internal;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlOptions;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTComment;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTComments;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CommentsDocument;

import javax.xml.namespace.QName;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import static org.apache.poi.ooxml.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;

/**
 * specifies all of the comments defined in the current document
 */
public class XWPFComments extends POIXMLDocumentPart {

    XWPFDocument document;
    private List<XWPFComment> comments = new ArrayList<>();
    private List<XWPFPictureData> pictures = new ArrayList<>();
    private CTComments ctComments;

    /**
     * Construct XWPFComments from a package part
     *
     * @param part the package part holding the data of the footnotes,
     */
    public XWPFComments(PackagePart part) {
        super(part);
    }

    /**
     * Construct XWPFComments from scratch for a new document.
     */
    public XWPFComments() {
        ctComments = CTComments.Factory.newInstance();
    }

    /**
     * read comments form an existing package
     */
    @Override
    public void onDocumentRead() throws IOException {
        try (InputStream is = getPackagePart().getInputStream()) {
            CommentsDocument doc = CommentsDocument.Factory.parse(is, DEFAULT_XML_OPTIONS);
            ctComments = doc.getComments();
            for (CTComment ctComment : ctComments.getCommentList()) {
                comments.add(new XWPFComment(ctComment, this));
            }
        } catch (XmlException e) {
            throw new POIXMLException("Unable to read comments", e);
        }

        for (POIXMLDocumentPart poixmlDocumentPart : getRelations()) {
            if (poixmlDocumentPart instanceof XWPFPictureData) {
                XWPFPictureData xwpfPicData = (XWPFPictureData) poixmlDocumentPart;
                pictures.add(xwpfPicData);
                document.registerPackagePictureData(xwpfPicData);
            }
        }
    }

    /**
     * Adds a picture to the comments.
     *
     * @param is     The stream to read image from
     * @param format The format of the picture.
     * @return the index to this picture (0 based), the added picture can be
     * obtained from {@link #getAllPictures()} .
     * @throws InvalidFormatException If the format of the picture is not known.
     * @throws IOException            If reading the picture-data from the stream fails.
     */
    public String addPictureData(InputStream is, int format) throws InvalidFormatException, IOException {
        byte[] data = IOUtils.toByteArray(is);
        return addPictureData(data, format);
    }

    /**
     * Adds a picture to the comments.
     *
     * @param pictureData The picture data
     * @param format      The format of the picture.
     * @return the index to this picture (0 based), the added picture can be
     * obtained from {@link #getAllPictures()} .
     * @throws InvalidFormatException If the format of the picture is not known.
     */
    public String addPictureData(byte[] pictureData, int format) throws InvalidFormatException {
        XWPFPictureData xwpfPicData = document.findPackagePictureData(pictureData, format);
        POIXMLRelation relDesc = XWPFPictureData.RELATIONS[format];

        if (xwpfPicData == null) {
            /* Part doesn't exist, create a new one */
            int idx = getXWPFDocument().getNextPicNameNumber(format);
            xwpfPicData = (XWPFPictureData) createRelationship(relDesc, XWPFFactory.getInstance(), idx);
            /* write bytes to new part */
            PackagePart picDataPart = xwpfPicData.getPackagePart();
            try (OutputStream out = picDataPart.getOutputStream()) {
                out.write(pictureData);
            } catch (IOException e) {
                throw new POIXMLException(e);
            }

            document.registerPackagePictureData(xwpfPicData);
            pictures.add(xwpfPicData);
            return getRelationId(xwpfPicData);
        } else if (!getRelations().contains(xwpfPicData)) {
            /*
             * Part already existed, but was not related so far. Create
             * relationship to the already existing part and update
             * POIXMLDocumentPart data.
             */
            // TODO add support for TargetMode.EXTERNAL relations.
            RelationPart rp = addRelation(null, XWPFRelation.IMAGES, xwpfPicData);
            pictures.add(xwpfPicData);
            return rp.getRelationship().getId();
        } else {
            /* Part already existed, get relation id and return it */
            return getRelationId(xwpfPicData);
        }
    }

    /**
     * save and commit comments
     */
    @Override
    protected void commit() throws IOException {
        XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
        xmlOptions.setSaveSyntheticDocumentElement(new QName(
                CTComments.type.getName().getNamespaceURI(), "comments"));
        PackagePart part = getPackagePart();
        OutputStream out = part.getOutputStream();
        ctComments.save(out, xmlOptions);
        out.close();
    }

    public List<XWPFPictureData> getAllPictures() {
        return Collections.unmodifiableList(pictures);
    }

    /**
     * Gets the underlying CTComments object for the comments.
     *
     * @return CTComments object
     */
    public CTComments getCtComments() {
        return ctComments;
    }

    /**
     * set a new comments
     */
    @Internal
    public void setCtComments(CTComments ctComments) {
        this.ctComments = ctComments;
    }

    /**
     * Get the list of {@link XWPFComment} in the Comments part.
     *
     * @return
     */
    public List<XWPFComment> getComments() {
        return comments;
    }

    /**
     * Get the specified comment by position
     *
     * @param pos Array position of the comment
     * @return
     */
    public XWPFComment getComment(int pos) {
        if (pos >= 0 && pos < ctComments.sizeOfCommentArray()) {
            return getComments().get(pos);
        }
        return null;
    }

    /**
     * Get the specified comment by comment id
     *
     * @param id comment id
     * @return the specified comment
     */
    public XWPFComment getCommentByID(String id) {
        for (XWPFComment comment : comments) {
            if (comment.getId().equals(id)) {
                return comment;
            }
        }
        return null;
    }

    /**
     * Get the specified comment by ctComment
     *
     * @param ctComment
     * @return
     */
    public XWPFComment getComment(CTComment ctComment) {
        for (int i = 0; i < comments.size(); i++) {
            if (comments.get(i).getCtComment() == ctComment) {
                return comments.get(i);
            }
        }
        return null;
    }

    /**
     * Create a new comment and add it to the document.
     *
     * @param cid comment Id
     * @return
     */
    public XWPFComment createComment(BigInteger cid) {
        CTComment ctComment = ctComments.addNewComment();
        ctComment.setId(cid);
        XWPFComment comment = new XWPFComment(ctComment, this);
        comments.add(comment);
        return comment;
    }

    /**
     * Remove the specified comment if present.
     *
     * @param pos Array position of the comment to be removed
     * @return True if the comment was removed.
     */
    public boolean removeComment(int pos) {
        if (pos >= 0 && pos < ctComments.sizeOfCommentArray()) {
            comments.remove(pos);
            ctComments.removeComment(pos);
            return true;
        }
        return false;
    }

    public XWPFDocument getXWPFDocument() {
        if (null != document) {
            return document;
        }
        return (XWPFDocument) getParent();
    }

    public void setXWPFDocument(XWPFDocument document) {
        this.document = document;
    }

}
