/*
 * 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.sling.jcr.contentloader.internal;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

import org.apache.sling.commons.osgi.ManifestHeader;
import org.apache.sling.jcr.contentloader.ImportOptions;
import org.osgi.framework.Bundle;

/**
 * A path entry from the manifest for initial content.
 */
public class PathEntry extends ImportOptions {

    /** The manifest header to specify initial content to be loaded. */
    public static final String CONTENT_HEADER = "Sling-Initial-Content";

    /**
     * The overwrite directive specifying if content should be overwritten or
     * just initially added.
     */
    public static final String OVERWRITE_DIRECTIVE = "overwrite";

    /**
     * The overwriteProperties directive specifying if content properties 
     * should be overwritten or just initially added.
     */
    public static final String OVERWRITE_PROPERTIES_DIRECTIVE = "overwriteProperties";
    
    /**
     * The overwriteProperties directive specifying if content properties 
     * should be overwritten or just initially added.
     */
    public static final String MERGE_PROPERTIES_DIRECTIVE = "mergeProperties";
    
    /**
     * The overwriteProperties directive specifying if content properties 
     * should be overwritten or just initially added.
     */
    public static final String MERGE_NODES_DIRECTIVE = "merge";

    /** The uninstall directive specifying if content should be uninstalled. */
    public static final String UNINSTALL_DIRECTIVE = "uninstall";

    /**
     * The path directive specifying the target node where initial content will
     * be loaded.
     */
    public static final String PATH_DIRECTIVE = "path";

    /**
     * The workspace into which the content will be loaded.
     */
    public static final String WORKSPACE_DIRECTIVE = "workspace";

    /**
     * The checkin directive specifying whether versionable nodes should be
     * checked in
     */
    public static final String CHECKIN_DIRECTIVE = "checkin";

    /**
     * The autoCheckout directive specifying whether versionable nodes should be
     * checked out when necessary
     */
    public static final String AUTOCHECKOUT_DIRECTIVE = "autoCheckout";

    /**
     * The ignore content readers directive specifying whether the available 
     * {@link org.apache.sling.jcr.contentloader.ContentReader}s should be used during
     * content loading. This is a string value that defaults to the emptystring.
     * @since 2.0.4
     */
    public static final String IGNORE_CONTENT_READERS_DIRECTIVE = "ignoreImportProviders";

    /**
     * If the content should be skipped with a particular runmode. By
     * default this will be an empty string which means the content will be
     * installed regardless of the runmode
     * @since 2.4.0
     */
    public static final String SKIP_RUNMODE = "skipRunmode";

    private final boolean propertyMerge;
    
    private final boolean nodeMerge;

    /** The path for the initial content. */
    private final String path;

    /** Should existing content be overwritten? */
    private final boolean overwrite;

    /** Should existing content properties be overwritten? */
    private final boolean overwriteProperties;

    /** The content at the path will be skipped for this runmode */
    private final String skipRunmode;

    /** Should existing content be uninstalled? */
    private final boolean uninstall;

    /** Should versionable nodes be checked in? */
    private final boolean checkin;

    /** Should versionable nodes be auto checked out when necessary? */
    private final boolean autoCheckout;
    
    /** Which content readers should be ignored? @since 2.0.4 */
    private final List<String> ignoreContentReaders;

    /**
     * Target path where initial content will be loaded. If it´s null then
     * target node is the root node
     */
    private final String target;

    /** Workspace to import into. */
    private final String workspace;

    private long lastModified;

    public static Iterator<PathEntry> getContentPaths(final Bundle bundle) {
        final List<PathEntry> entries = new ArrayList<>();
        String bundleLastModifiedStamp = bundle.getHeaders().get("Bnd-LastModified");
        long bundleLastModified = bundle.getLastModified(); // time last modified inside the container
        if ( bundleLastModifiedStamp != null ) {
            bundleLastModified = Math.min(bundleLastModified, Long.parseLong(bundleLastModifiedStamp));
        }
        final String root = bundle.getHeaders().get(CONTENT_HEADER);
        if (root != null) {
            final ManifestHeader header = ManifestHeader.parse(root);
            for (final ManifestHeader.Entry entry : header.getEntries()) {
                
                entries.add(new PathEntry(entry, bundleLastModified ));
            }
        }

        if (entries.isEmpty()) {
            return null;
        }
        return entries.iterator();
    }

    public PathEntry(ManifestHeader.Entry entry, long bundleLastModified) {
        this.path = entry.getValue();
        this.lastModified = bundleLastModified;

        // check for directives

        // merge directive
        final String mergeProperties = entry.getDirectiveValue(MERGE_PROPERTIES_DIRECTIVE);
        if (mergeProperties != null) {
            this.propertyMerge = Boolean.valueOf(mergeProperties);
        } else {
            this.propertyMerge = false;
        }
        
        // merge directive
        final String mergeNodes = entry.getDirectiveValue(MERGE_NODES_DIRECTIVE);
        if (mergeNodes != null) {
            this.nodeMerge = Boolean.valueOf(mergeProperties);
        } else {
            this.nodeMerge = false;
        }
        
        // overwrite directive
        final String overwriteValue = entry.getDirectiveValue(OVERWRITE_DIRECTIVE);
        if (overwriteValue != null) {
            this.overwrite = Boolean.valueOf(overwriteValue);
        } else {
            this.overwrite = false;
        }

        // overwriteProperties directive
        final String overwritePropertiesValue = entry.getDirectiveValue(OVERWRITE_PROPERTIES_DIRECTIVE);
        if (overwritePropertiesValue != null) {
            this.overwriteProperties = Boolean.valueOf(overwritePropertiesValue);
        } else {
            this.overwriteProperties = false;
        }
        
 
        // uninstall directive
        final String uninstallValue = entry.getDirectiveValue(UNINSTALL_DIRECTIVE);
        if (uninstallValue != null) {
            this.uninstall = Boolean.valueOf(uninstallValue);
        } else {
            this.uninstall = this.overwrite;
        }

        // path directive
        final String pathValue = entry.getDirectiveValue(PATH_DIRECTIVE);
        if (pathValue != null) {
            this.target = pathValue;
        } else {
            this.target = null;
        }

        // checkin directive
        final String checkinValue = entry.getDirectiveValue(CHECKIN_DIRECTIVE);
        if (checkinValue != null) {
            this.checkin = Boolean.valueOf(checkinValue);
        } else {
            this.checkin = false;
        }

        // autoCheckout directive
        final String autoCheckoutValue = entry.getDirectiveValue(AUTOCHECKOUT_DIRECTIVE);
        if (autoCheckoutValue != null) {
            this.autoCheckout = Boolean.valueOf(autoCheckoutValue);
        } else {
            this.autoCheckout = true;
        }

        // expand directive
        this.ignoreContentReaders = new ArrayList<>();
        final String expandValue = entry.getDirectiveValue(IGNORE_CONTENT_READERS_DIRECTIVE);
        if ( expandValue != null && expandValue.length() > 0 ) {
            final StringTokenizer st = new StringTokenizer(expandValue, ",");
            while ( st.hasMoreTokens() ) {
                this.ignoreContentReaders.add(st.nextToken());
            }
        }

        // workspace directive
        this.skipRunmode = entry.getDirectiveValue(SKIP_RUNMODE);

        // workspace directive
        final String workspaceValue = entry.getDirectiveValue(WORKSPACE_DIRECTIVE);
        if (pathValue != null) {
            this.workspace = workspaceValue;
        } else {
            this.workspace = null;
        }
    }
    
    public long getLastModified() {
        return lastModified;
    }
    
    public String getPath() {
        return this.path;
    }

    /* (non-Javadoc)
     * @see org.apache.sling.jcr.contentloader.internal.ImportOptions#isOverwrite()
     */
    public boolean isOverwrite() {
        return this.overwrite;
    }

    /* (non-Javadoc)
     * @see org.apache.sling.jcr.contentloader.ImportOptions#isPropertyOverwrite()
     */

    public boolean isPropertyOverwrite() {
        return this.overwriteProperties;
    }

    public boolean isUninstall() {
        return this.uninstall;
    }

    /* (non-Javadoc)
     * @see org.apache.sling.jcr.contentloader.internal.ImportOptions#isCheckin()
     */
    public boolean isCheckin() {
        return this.checkin;
    }
    
    /* (non-Javadoc)
     * @see org.apache.sling.jcr.contentloader.ImportOptions#isAutoCheckout()
     */

    public boolean isAutoCheckout() {
        return this.autoCheckout;
    }

    /* (non-Javadoc)
     * @see org.apache.sling.jcr.contentloader.internal.ImportOptions#isIgnoredImportProvider(java.lang.String)
     */
    public boolean isIgnoredImportProvider(String extension) {
        if ( extension.startsWith(".") ) {
            extension = extension.substring(1);
        }
        return this.ignoreContentReaders.contains(extension);
    }

    public String getSkipRunmode(){
        return this.skipRunmode;
    }

    public String getTarget() {
        return target;
    }

    public String getWorkspace() {
        return workspace;
    }

    public boolean isPropertyMerge() {
        return this.propertyMerge;
    }

    public boolean isMerge() {
        return this.nodeMerge;
    }
}
