/* ====================================================================
   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.compliance;

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;

import org.apache.poi.POIDataSamples;
import org.apache.poi.openxml4j.OpenXML4JTestDataSamples;
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.PackageRelationshipTypes;
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.openxml4j.opc.TargetMode;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.TempFile;
import org.junit.Test;

import junit.framework.AssertionFailedError;

/**
 * Test core properties Open Packaging Convention compliance.
 * 
 * M4.1: The format designer shall specify and the format producer shall create
 * at most one core properties relationship for a package. A format consumer
 * shall consider more than one core properties relationship for a package to be
 * an error. If present, the relationship shall target the Core Properties part.
 * (POI relaxes this on reading, as Office sometimes breaks this)
 * 
 * M4.2: The format designer shall not specify and the format producer shall not
 * create Core Properties that use the Markup Compatibility namespace as defined
 * in Annex F, "Standard Namespaces and Content Types". A format consumer shall
 * consider the use of the Markup Compatibility namespace to be an error.
 * 
 * M4.3: Producers shall not create a document element that contains refinements
 * to the Dublin Core elements, except for the two specified in the schema:
 * <dcterms:created> and <dcterms:modified> Consumers shall consider a document
 * element that violates this constraint to be an error.
 * 
 * M4.4: Producers shall not create a document element that contains the
 * xml:lang attribute. Consumers shall consider a document element that violates
 * this constraint to be an error.
 * 
 * M4.5: Producers shall not create a document element that contains the
 * xsi:type attribute, except for a <dcterms:created> or <dcterms:modified>
 * element where the xsi:type attribute shall be present and shall hold the
 * value dcterms:W3CDTF, where dcterms is the namespace prefix of the Dublin
 * Core namespace. Consumers shall consider a document element that violates
 * this constraint to be an error.
 * 
 * @author Julien Chable
 */
public final class TestOPCComplianceCoreProperties {

    @Test
    public void testCorePropertiesPart() {
        OPCPackage pkg;
        try {
            InputStream is = OpenXML4JTestDataSamples.openComplianceSampleStream("OPCCompliance_CoreProperties_OnlyOneCorePropertiesPart.docx");
            pkg = OPCPackage.open(is);
        } catch (InvalidFormatException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        pkg.revert();
    }

    private static String extractInvalidFormatMessage(String sampleNameSuffix) {
        InputStream is = OpenXML4JTestDataSamples.openComplianceSampleStream("OPCCompliance_CoreProperties_" + sampleNameSuffix);
        OPCPackage pkg;
        try {
            pkg = OPCPackage.open(is);
        } catch (InvalidFormatException e) {
            // no longer required for successful test
            return e.getMessage();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        pkg.revert();
        throw new AssertionFailedError("expected OPC compliance exception was not thrown");
    }
    
    /**
     * Test M4.1 rule.
     */
    @Test
    public void testOnlyOneCorePropertiesPart() throws Exception {
       // We have relaxed this check, so we can read the file anyway
       try {
          extractInvalidFormatMessage("OnlyOneCorePropertiesPartFAIL.docx");
          fail("M4.1 should be being relaxed");
       } catch (AssertionFailedError e) {
           // expected here
       }
       
       // We will use the first core properties, and ignore the others
      InputStream is = OpenXML4JTestDataSamples.openSampleStream("MultipleCoreProperties.docx");
      OPCPackage pkg = OPCPackage.open(is);
      
      // We can see 2 by type
      assertEquals(2, pkg.getPartsByContentType(ContentTypes.CORE_PROPERTIES_PART).size());
      // But only the first one by relationship
      assertEquals(1, pkg.getPartsByRelationshipType(PackageRelationshipTypes.CORE_PROPERTIES).size());
      // It should be core.xml not the older core1.xml
      assertEquals(
            "/docProps/core.xml",
            pkg.getPartsByRelationshipType(PackageRelationshipTypes.CORE_PROPERTIES).get(0).getPartName().toString()
      );
    }
    
    private static URI createURI(String text) {
        try {
            return new URI(text);
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Test M4.1 rule.
     */
    @Test
    public void testOnlyOneCorePropertiesPart_AddRelationship() {
        InputStream is = OpenXML4JTestDataSamples.openComplianceSampleStream("OPCCompliance_CoreProperties_OnlyOneCorePropertiesPart.docx");
        OPCPackage pkg;
        try {
            pkg = OPCPackage.open(is);
        } catch (InvalidFormatException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        URI partUri = createURI("/docProps/core2.xml");
        try {
            pkg.addRelationship(PackagingURIHelper.createPartName(partUri), TargetMode.INTERNAL,
                    PackageRelationshipTypes.CORE_PROPERTIES);
            // no longer fail on compliance error
            //fail("expected OPC compliance exception was not thrown");
        } catch (InvalidFormatException e) {
            throw new RuntimeException(e);
        } catch (InvalidOperationException e) {
            // expected during successful test
            assertEquals("OPC Compliance error [M4.1]: can't add another core properties part ! Use the built-in package method instead.", e.getMessage());
        }
        pkg.revert();
    }

    /**
     * Test M4.1 rule.
     */
    @Test
    public void testOnlyOneCorePropertiesPart_AddPart() throws InvalidFormatException {
        String sampleFileName = "OPCCompliance_CoreProperties_OnlyOneCorePropertiesPart.docx";
        OPCPackage pkg = OPCPackage.open(POIDataSamples.getOpenXML4JInstance().getFile(sampleFileName).getPath());

        URI partUri = createURI("/docProps/core2.xml");
        try {
            pkg.createPart(PackagingURIHelper.createPartName(partUri),
                    ContentTypes.CORE_PROPERTIES_PART);
            // no longer fail on compliance error
            //fail("expected OPC compliance exception was not thrown");
        } catch (InvalidOperationException e) {
            // expected during successful test
            assertEquals("OPC Compliance error [M4.1]: you try to add more than one core properties relationship in the package !", e.getMessage());
        }
        pkg.revert();
    }

    /**
     * Test M4.2 rule.
     */
    @Test
    public void testDoNotUseCompatibilityMarkup() {
        String msg = extractInvalidFormatMessage("DoNotUseCompatibilityMarkupFAIL.docx");
        assertEquals("OPC Compliance error [M4.2]: A format consumer shall consider the use of the Markup Compatibility namespace to be an error.", msg);
    }

    /**
     * Test M4.3 rule.
     */
    @Test
    public void testDCTermsNamespaceLimitedUse() {
        String msg = extractInvalidFormatMessage("DCTermsNamespaceLimitedUseFAIL.docx");
        assertEquals("OPC Compliance error [M4.3]: Producers shall not create a document element that contains refinements to the Dublin Core elements, except for the two specified in the schema: <dcterms:created> and <dcterms:modified> Consumers shall consider a document element that violates this constraint to be an error.", msg);
    }

    /**
     * Test M4.4 rule.
     */
    @Test
    public void testUnauthorizedXMLLangAttribute() {
        String msg = extractInvalidFormatMessage("UnauthorizedXMLLangAttributeFAIL.docx");
        assertEquals("OPC Compliance error [M4.4]: Producers shall not create a document element that contains the xml:lang attribute. Consumers shall consider a document element that violates this constraint to be an error.", msg);
    }

    /**
     * Test M4.5 rule.
     */
    @Test
    public void testLimitedXSITypeAttribute_NotPresent() {
        String msg = extractInvalidFormatMessage("LimitedXSITypeAttribute_NotPresentFAIL.docx");
        assertEquals("The element 'created' must have the 'xsi:type' attribute present !", msg);
    }

    /**
     * Test M4.5 rule.
     */
    @Test
    public void testLimitedXSITypeAttribute_PresentWithUnauthorizedValue() {
        String msg = extractInvalidFormatMessage("LimitedXSITypeAttribute_PresentWithUnauthorizedValueFAIL.docx");
        assertEquals("The element 'modified' must have the 'xsi:type' attribute with the value 'dcterms:W3CDTF', but had 'W3CDTF' !", msg);
    }
    
    /**
     * Document with no core properties - testing at the OPC level,
     *  saving into a new stream
     */
    @Test
    public void testNoCoreProperties_saveNew() throws Exception {
        String sampleFileName = "OPCCompliance_NoCoreProperties.xlsx";
        OPCPackage pkg = OPCPackage.open(POIDataSamples.getOpenXML4JInstance().getFile(sampleFileName).getPath());

        // Verify it has empty properties
        assertEquals(0, pkg.getPartsByContentType(ContentTypes.CORE_PROPERTIES_PART).size());
        assertNotNull(pkg.getPackageProperties());
        assertNotNull(pkg.getPackageProperties().getLanguageProperty());
        assertNull(pkg.getPackageProperties().getLanguageProperty().getValue());

        // Save and re-load
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        pkg.save(baos);
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
        pkg.revert();

        pkg = OPCPackage.open(bais);

        // An Empty Properties part has been added in the save/load
        assertEquals(1, pkg.getPartsByContentType(ContentTypes.CORE_PROPERTIES_PART).size());
        assertNotNull(pkg.getPackageProperties());
        assertNotNull(pkg.getPackageProperties().getLanguageProperty());
        assertNull(pkg.getPackageProperties().getLanguageProperty().getValue());
        pkg.close();
        
        // Open a new copy of it
        pkg = OPCPackage.open(POIDataSamples.getOpenXML4JInstance().getFile(sampleFileName).getPath());
        
        // Save and re-load, without having touched the properties yet
        baos = new ByteArrayOutputStream();
        pkg.save(baos);
        pkg.revert();

        bais = new ByteArrayInputStream(baos.toByteArray());
        pkg = OPCPackage.open(bais);
        
        // Check that this too added empty properties without error
        assertEquals(1, pkg.getPartsByContentType(ContentTypes.CORE_PROPERTIES_PART).size());
        assertNotNull(pkg.getPackageProperties());
        assertNotNull(pkg.getPackageProperties().getLanguageProperty());
        assertNull(pkg.getPackageProperties().getLanguageProperty().getValue());
    }

    /**
     * Document with no core properties - testing at the OPC level,
     *  from a temp-file, saving in-place
     */
    @Test
    public void testNoCoreProperties_saveInPlace() throws Exception {
        String sampleFileName = "OPCCompliance_NoCoreProperties.xlsx";

        // Copy this into a temp file, so we can play with it
        File tmp = TempFile.createTempFile("poi-test", ".opc");
        FileOutputStream out = new FileOutputStream(tmp);
        InputStream in = POIDataSamples.getOpenXML4JInstance().openResourceAsStream(sampleFileName);
        IOUtils.copy(
                in,
                out);
        out.close();
        in.close();

        // Open it from that temp file
        OPCPackage pkg = OPCPackage.open(tmp);

        // Empty properties
        assertEquals(0, pkg.getPartsByContentType(ContentTypes.CORE_PROPERTIES_PART).size());
        assertNotNull(pkg.getPackageProperties());
        assertNotNull(pkg.getPackageProperties().getLanguageProperty());
        assertNull(pkg.getPackageProperties().getLanguageProperty().getValue());

        // Save and close
        pkg.close();

        // Re-open and check
        pkg = OPCPackage.open(tmp);

        // An Empty Properties part has been added in the save/load
        assertEquals(1, pkg.getPartsByContentType(ContentTypes.CORE_PROPERTIES_PART).size());
        assertNotNull(pkg.getPackageProperties());
        assertNotNull(pkg.getPackageProperties().getLanguageProperty());
        assertNull(pkg.getPackageProperties().getLanguageProperty().getValue());

        // Finish and tidy
        pkg.revert();
        assertTrue(tmp.delete());
    }
}
