/* ====================================================================
   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.openxml4j.opc.internal;

import java.io.InputStream;
import java.io.OutputStream;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
import org.apache.poi.openxml4j.opc.ContentTypes;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageNamespaces;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackagePartName;
import org.apache.poi.openxml4j.opc.PackageProperties;
import org.apache.poi.util.LocaleUtil;

/**
 * Represents the core properties part of a package.
 */
public final class PackagePropertiesPart extends PackagePart implements PackageProperties {

    public static final String NAMESPACE_DC_URI = PackageProperties.NAMESPACE_DC;

    public static final String NAMESPACE_CP_URI = PackageNamespaces.CORE_PROPERTIES;

    public static final String NAMESPACE_DCTERMS_URI = PackageProperties.NAMESPACE_DCTERMS;

    private static final String DEFAULT_DATEFORMAT =   "yyyy-MM-dd'T'HH:mm:ss'Z'";

    private static final String[] DATE_FORMATS = new String[]{
            DEFAULT_DATEFORMAT,
            "yyyy-MM-dd'T'HH:mm:ss.SS'Z'",
            "yyyy-MM-dd"
    };

    //Had to add this and TIME_ZONE_PAT to handle tz with colons.
    //When we move to Java 7, we should be able to add another
    //date format to DATE_FORMATS that uses XXX and get rid of this
    //and TIME_ZONE_PAT
    // TODO Fix this after the Java 7 upgrade
    private final String[] TZ_DATE_FORMATS = new String[]{
            "yyyy-MM-dd'T'HH:mm:ssz",
            "yyyy-MM-dd'T'HH:mm:ss.Sz",
            "yyyy-MM-dd'T'HH:mm:ss.SSz",
            "yyyy-MM-dd'T'HH:mm:ss.SSSz",
    };

    private final Pattern TIME_ZONE_PAT = Pattern.compile("([-+]\\d\\d):?(\\d\\d)");
    /**
     * Constructor.
     *
     * @param pack
     *            Container package.
     * @param partName
     *            Name of this part.
     * @throws InvalidFormatException
     *             Throws if the content is invalid.
     */
    public PackagePropertiesPart(OPCPackage pack, PackagePartName partName)
            throws InvalidFormatException {
        super(pack, partName, ContentTypes.CORE_PROPERTIES_PART);
    }

    /**
     * A categorization of the content of this package.
     *
     * [Example: Example values for this property might include: Resume, Letter,
     * Financial Forecast, Proposal, Technical Presentation, and so on. This
     * value might be used by an application's user interface to facilitate
     * navigation of a large set of documents. end example]
     */
    protected Optional<String> category = Optional.empty();

    /**
     * The status of the content.
     *
     * [Example: Values might include "Draft", "Reviewed", and "Final". end
     * example]
     */
    protected Optional<String> contentStatus = Optional.empty();

    /**
     * The type of content represented, generally defined by a specific use and
     * intended audience.
     *
     * [Example: Values might include "Whitepaper", "Security Bulletin", and
     * "Exam". end example] [Note: This property is distinct from MIME content
     * types as defined in RFC 2616. end note]
     */
    protected Optional<String> contentType = Optional.empty();

    /**
     * Date of creation of the resource.
     */
    protected Optional<Date> created = Optional.empty();

    /**
     * An entity primarily responsible for making the content of the resource.
     */
    protected Optional<String> creator = Optional.empty();

    /**
     * An explanation of the content of the resource.
     *
     * [Example: Values might include an abstract, table of contents, reference
     * to a graphical representation of content, and a free-text account of the
     * content. end example]
     */
    protected Optional<String> description = Optional.empty();

    /**
     * An unambiguous reference to the resource within a given context.
     */
    protected Optional<String> identifier = Optional.empty();

    /**
     * A delimited set of keywords to support searching and indexing. This is
     * typically a list of terms that are not available elsewhere in the
     * properties.
     */
    protected Optional<String> keywords = Optional.empty();

    /**
     * The language of the intellectual content of the resource.
     *
     * [Note: IETF RFC 3066 provides guidance on encoding to represent
     * languages. end note]
     */
    protected Optional<String> language = Optional.empty();

    /**
     * The user who performed the last modification. The identification is
     * environment-specific.
     *
     * [Example: A name, email address, or employee ID. end example] It is
     * recommended that this value be as concise as possible.
     */
    protected Optional<String> lastModifiedBy = Optional.empty();

    /**
     * The date and time of the last printing.
     */
    protected Optional<Date> lastPrinted = Optional.empty();

    /**
     * Date on which the resource was changed.
     */
    protected Optional<Date> modified = Optional.empty();

    /**
     * The revision number.
     *
     * [Example: This value might indicate the number of saves or revisions,
     * provided the application updates it after each revision. end example]
     */
    protected Optional<String> revision = Optional.empty();

    /**
     * The topic of the content of the resource.
     */
    protected Optional<String> subject = Optional.empty();

    /**
     * The name given to the resource.
     */
    protected Optional<String> title = Optional.empty();

    /**
     * The version number. This value is set by the user or by the application.
     */
    protected Optional<String> version = Optional.empty();

    /*
     * Getters and setters
     */

    /**
     * Get the category property.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#getCategoryProperty()
     */
    public Optional<String> getCategoryProperty() {
        return category;
    }

    /**
     * Get content status.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#getContentStatusProperty()
     */
    public Optional<String> getContentStatusProperty() {
        return contentStatus;
    }

    /**
     * Get content type.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#getContentTypeProperty()
     */
    public Optional<String> getContentTypeProperty() {
        return contentType;
    }

    /**
     * Get created date.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#getCreatedProperty()
     */
    public Optional<Date> getCreatedProperty() {
        return created;
    }

    /**
     * Get created date formated into a String.
     *
     * @return A string representation of the created date.
     */
    public String getCreatedPropertyString() {
        return getDateValue(created);
    }

    /**
     * Get creator.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#getCreatorProperty()
     */
    public Optional<String> getCreatorProperty() {
        return creator;
    }

    /**
     * Get description.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#getDescriptionProperty()
     */
    public Optional<String> getDescriptionProperty() {
        return description;
    }

    /**
     * Get identifier.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#getIdentifierProperty()
     */
    public Optional<String> getIdentifierProperty() {
        return identifier;
    }

    /**
     * Get keywords.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#getKeywordsProperty()
     */
    public Optional<String> getKeywordsProperty() {
        return keywords;
    }

    /**
     * Get the language.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#getLanguageProperty()
     */
    public Optional<String> getLanguageProperty() {
        return language;
    }

    /**
     * Get the author of last modifications.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#getLastModifiedByProperty()
     */
    public Optional<String> getLastModifiedByProperty() {
        return lastModifiedBy;
    }

    /**
     * Get last printed date.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#getLastPrintedProperty()
     */
    public Optional<Date> getLastPrintedProperty() {
        return lastPrinted;
    }

    /**
     * Get last printed date formated into a String.
     *
     * @return A string representation of the last printed date.
     */
    public String getLastPrintedPropertyString() {
        return getDateValue(lastPrinted);
    }

    /**
     * Get modified date.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#getModifiedProperty()
     */
    public Optional<Date> getModifiedProperty() {
        return modified;
    }

    /**
     * Get modified date formated into a String.
     *
     * @return A string representation of the modified date.
     */
    public String getModifiedPropertyString() {
        if (modified.isPresent()) {
            return getDateValue(modified);
        }
        return getDateValue(Optional.of(new Date()));
    }

    /**
     * Get revision.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#getRevisionProperty()
     */
    public Optional<String> getRevisionProperty() {
        return revision;
    }

    /**
     * Get subject.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#getSubjectProperty()
     */
    public Optional<String> getSubjectProperty() {
        return subject;
    }

    /**
     * Get title.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#getTitleProperty()
     */
    public Optional<String> getTitleProperty() {
        return title;
    }

    /**
     * Get version.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#getVersionProperty()
     */
    public Optional<String> getVersionProperty() {
        return version;
    }

    /**
     * Set the category.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setCategoryProperty(java.lang.String)
     */
    public void setCategoryProperty(String category) {
        this.category = setStringValue(category);
    }

    /**
     * Set the category.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setCategoryProperty(java.util.Optional)
     */
    public void setCategoryProperty(Optional<String> category) { this.category = category; }

    /**
     * Set the content status.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setContentStatusProperty(java.lang.String)
     */
    public void setContentStatusProperty(String contentStatus) {
        this.contentStatus = setStringValue(contentStatus);
    }

    /**
     * Set the content status.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setContentStatusProperty(java.util.Optional)
     */
    public void setContentStatusProperty(Optional<String> contentStatus) { this.contentStatus = contentStatus; }

    /**
     * Set the content type.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setContentTypeProperty(java.lang.String)
     */
    public void setContentTypeProperty(String contentType) {
        this.contentType = setStringValue(contentType);
    }

    /**
     * Set the content type.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setContentTypeProperty(java.util.Optional)
     */
    public void setContentTypeProperty(Optional<String> contentType) { this.contentType = contentType; }

    /**
     * Set the created date.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setCreatedProperty(java.util.Optional)
     */
    public void setCreatedProperty(String created) {
        try {
            this.created = setDateValue(created);
        } catch (InvalidFormatException e) {
            throw new IllegalArgumentException("Date for created could not be parsed: " + created, e);
        }
    }

    /**
     * Set the created date.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setCreatedProperty(java.util.Optional)
     */
    public void setCreatedProperty(Optional<Date> created) {
        if (created.isPresent())
            this.created = created;
    }

    /**
     * Set the creator.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setCreatorProperty(java.lang.String)
     */
    public void setCreatorProperty(String creator) {
        this.creator = setStringValue(creator);
    }

    /**
     * Set the creator.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setCreatorProperty(java.util.Optional)
     */
    public void setCreatorProperty(Optional<String> creator) { this.creator = creator; }

    /**
     * Set the description.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setDescriptionProperty(java.lang.String)
     */
    public void setDescriptionProperty(String description) {
        this.description = setStringValue(description);
    }

    /**
     * Set the description.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setDescriptionProperty(java.util.Optional)
     */
    public void setDescriptionProperty(Optional<String> description) { this.description = description; }

    /**
     * Set identifier.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setIdentifierProperty(java.lang.String)
     */
    public void setIdentifierProperty(String identifier) {
        this.identifier = setStringValue(identifier);
    }

    /**
     * Set identifier.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setIdentifierProperty(java.util.Optional)
     */
    public void setIdentifierProperty(Optional<String> identifier) { this.identifier = identifier; }

    /**
     * Set keywords.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setKeywordsProperty(java.lang.String)
     */
    public void setKeywordsProperty(String keywords) {
        this.keywords = setStringValue(keywords);
    }

    /**
     * Set keywords.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setKeywordsProperty(java.util.Optional)
     */
    public void setKeywordsProperty(Optional<String> keywords) { this.keywords = keywords; }

    /**
     * Set language.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setLanguageProperty(java.lang.String)
     */
    public void setLanguageProperty(String language) {
        this.language = setStringValue(language);
    }

    /**
     * Set language.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setLanguageProperty(java.util.Optional)
     */
    public void setLanguageProperty(Optional<String> language) { this.language = language; }

    /**
     * Set last modifications author.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setLastModifiedByProperty(java.lang.String)
     */
    public void setLastModifiedByProperty(String lastModifiedBy) {
        this.lastModifiedBy = setStringValue(lastModifiedBy);
    }

    /**
     * Set last modifications author.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setLastModifiedByProperty(java.util.Optional)
     */
    public void setLastModifiedByProperty(Optional<String> lastModifiedBy) {
        this.lastModifiedBy = lastModifiedBy;
    }

    /**
     * Set last printed date.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setLastPrintedProperty(java.util.Optional)
     */
    public void setLastPrintedProperty(String lastPrinted) {
        try {
            this.lastPrinted = setDateValue(lastPrinted);
        } catch (InvalidFormatException e) {
            throw new IllegalArgumentException("lastPrinted  : "
                    + e.getLocalizedMessage(), e);
        }
    }

    /**
     * Set last printed date.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setLastPrintedProperty(java.util.Optional)
     */
    public void setLastPrintedProperty(Optional<Date> lastPrinted) {
        if (lastPrinted.isPresent())
            this.lastPrinted = lastPrinted;
    }

    /**
     * Set last modification date.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setModifiedProperty(java.util.Optional)
     */
    public void setModifiedProperty(String modified) {
        try {
            this.modified = setDateValue(modified);
        } catch (InvalidFormatException e) {
            throw new IllegalArgumentException("modified  : "
                    + e.getLocalizedMessage(), e);
        }
    }

    /**
     * Set last modification date.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setModifiedProperty(java.util.Optional)
     */
    public void setModifiedProperty(Optional<Date> modified) {
        if (modified.isPresent())
            this.modified = modified;
    }

    /**
     * Set revision.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setRevisionProperty(java.util.Optional)
     */
    public void setRevisionProperty(Optional<String> revision) { this.revision = revision; }

    /**
     * Set revision.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setRevisionProperty(java.lang.String)
     */
    public void setRevisionProperty(String revision) {
        this.revision = setStringValue(revision);
    }
    /**
     * Set subject.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setSubjectProperty(java.lang.String)
     */
    public void setSubjectProperty(String subject) {
        this.subject = setStringValue(subject);
    }

    /**
     * Set subject.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setSubjectProperty(java.util.Optional)
     */
    public void setSubjectProperty(Optional<String> subject) { this.subject = subject; }

    /**
     * Set title.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setTitleProperty(java.lang.String)
     */
    public void setTitleProperty(String title) {
        this.title = setStringValue(title);
    }

    /**
     * Set title.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setTitleProperty(java.util.Optional)
     */
    public void setTitleProperty(Optional<String> title) { this.title = title; }

    /**
     * Set version.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setVersionProperty(java.lang.String)
     */
    public void setVersionProperty(String version) {
        this.version = setStringValue(version);
    }

    /**
     * Set version.
     *
     * @see org.apache.poi.openxml4j.opc.PackageProperties#setVersionProperty(java.util.Optional)
     */
    public void setVersionProperty(Optional<String> version) { this.version = version; }

    /**
     * Convert a string value into a Optional<String>
     */
    private Optional<String> setStringValue(String s) {
        if (s == null || s.isEmpty()) {
            return Optional.empty();
        }
        return Optional.of(s);
    }

    /**
     * Convert a string value represented a date into a Optional<Date>.
     *
     * @throws InvalidFormatException
     *             Throws if the date format isnot valid.
     */
    private Optional<Date> setDateValue(String dateStr) throws InvalidFormatException {
        if (dateStr == null || dateStr.isEmpty()) {
            return Optional.empty();
        }

        Matcher m = TIME_ZONE_PAT.matcher(dateStr);
        Date d = null;
        if (m.find()) {
            String dateTzStr = dateStr.substring(0, m.start())+m.group(1)+m.group(2);
            d = parseDateFormat(TZ_DATE_FORMATS, dateTzStr);
        }
        if (d == null) {
            String dateTzStr = dateStr.endsWith("Z") ? dateStr : (dateStr + "Z");
            d = parseDateFormat(DATE_FORMATS, dateTzStr);
        }
        if (d != null) {
            return Optional.of(d);
        }

        //if you're here, no pattern matched, throw exception
        String allFormats = Stream.of(TZ_DATE_FORMATS, DATE_FORMATS)
            .flatMap(Stream::of).collect(Collectors.joining(", "));
        throw new InvalidFormatException("Date " + dateStr + " not well formatted, expected format in: "+ allFormats);
    }

    private static Date parseDateFormat(String[] formats, String dateTzStr) {
        for (String fStr : formats) {
            SimpleDateFormat df = new SimpleDateFormat(fStr, Locale.ROOT);
            df.setTimeZone(LocaleUtil.TIMEZONE_UTC);
            Date d = df.parse(dateTzStr, new ParsePosition(0));
            if (d != null) {
                return d;
            }
        }
        return null;
    }

    /**
     * Convert a Optional<Date> into a String.
     *
     * @param d
     *            The Date to convert.
     * @return The formated date or null.
     * @see java.text.SimpleDateFormat
     */
    private static String getDateValue(Optional<Date> d) {
        return d.map(PackagePropertiesPart::getDateValue).orElse("");
    }

    private static String getDateValue(Date d) {
        SimpleDateFormat df = new SimpleDateFormat(DEFAULT_DATEFORMAT, Locale.ROOT);
        df.setTimeZone(LocaleUtil.TIMEZONE_UTC);
        return df.format(d);
    }

    @Override
    protected InputStream getInputStreamImpl() {
        throw new InvalidOperationException("Operation not authorized. This part may only be manipulated using the getters and setters on PackagePropertiesPart");
    }

    @Override
    protected OutputStream getOutputStreamImpl() {
        throw new InvalidOperationException(
                "Can't use output stream to set properties !");
    }

    @Override
    public boolean save(OutputStream zos) {
        throw new InvalidOperationException("Operation not authorized. This part may only be manipulated using the getters and setters on PackagePropertiesPart");
    }

    @Override
    public boolean load(InputStream ios) {
        throw new InvalidOperationException("Operation not authorized. This part may only be manipulated using the getters and setters on PackagePropertiesPart");
    }

    @Override
    public void close() {
        // Do nothing
    }

    @Override
    public void flush() {
        // Do nothing
    }
}
