/*
 * 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.launchpad.base.impl;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Map;

import org.apache.felix.framework.Logger;
import org.apache.sling.launchpad.api.LaunchpadContentProvider;
import org.apache.sling.launchpad.api.StartupMode;
import org.apache.sling.launchpad.base.shared.SharedConstants;
import org.osgi.framework.Constants;

/**
 * The <code>StartupManager</code> tries to detect the startup mode:
 * It distinguishes between an initial startup (INSTALL), an update (UPDATE)
 * and a restart without a change (RESTART).
 * @since 2.4.0
 */
public class StartupManager {

    /** The data file which works as a marker to detect the first startup. */
    private static final String DATA_FILE = "launchpad-timestamp.txt";

    /** The old data file. */
    private static final String OLD_DATA_FILE = "bundle0" + File.separatorChar + "bootstrapinstaller.ser";

    /** Name of the mode override property. */
    private static final String OVERRIDE_PROP = "org.apache.sling.launchpad.startupmode";

    /**
     * The {@link Logger} use for logging messages during installation and
     * startup.
     */
    private final Logger logger;

    private final StartupMode mode;

    private final File startupDir;

    private final File confDir;

    private final long targetStartLevel;

    private final boolean incrementalStartupEnabled;

    StartupManager(final Map<String, String> properties,
                   final Logger logger) {
        this.logger = logger;
        this.startupDir = DirectoryUtil.getStartupDir(properties);
        this.confDir = DirectoryUtil.getConfigDir(properties);
        // check for override property
        final String overrideMode = System.getProperty(OVERRIDE_PROP, properties.get(OVERRIDE_PROP));
        if ( overrideMode != null ) {
            this.mode = StartupMode.valueOf(overrideMode.toUpperCase());
            this.logger.log(Logger.LOG_INFO, "Override property set. Starting in mode " + this.mode);
        } else {
            this.mode = detectMode(properties.get(Constants.FRAMEWORK_STORAGE));
            this.logger.log(Logger.LOG_INFO, "Detected startup mode. Starting in mode " + this.mode);
        }

        // populate the sling target start level from the framework one, if not set,
        // otherwise overwrite the framework one
        if (null == properties.get(SharedConstants.SLING_INSTALL_TARGETSTARTLEVEL)) {
            properties.put(SharedConstants.SLING_INSTALL_TARGETSTARTLEVEL, properties.get(Constants.FRAMEWORK_BEGINNING_STARTLEVEL));
        } else {
            properties.put(Constants.FRAMEWORK_BEGINNING_STARTLEVEL, properties.get(SharedConstants.SLING_INSTALL_TARGETSTARTLEVEL));
        }

        this.targetStartLevel = Long.valueOf(properties.get(Constants.FRAMEWORK_BEGINNING_STARTLEVEL));

        this.incrementalStartupEnabled = Boolean.valueOf(properties.get(SharedConstants.SLING_INSTALL_INCREMENTAL_START));

        // if this is not a restart, reduce start level
        if ( this.mode != StartupMode.RESTART && this.incrementalStartupEnabled ) {
            final String startLevel = properties.get(SharedConstants.SLING_INSTALL_STARTLEVEL);
            properties.put(Constants.FRAMEWORK_BEGINNING_STARTLEVEL, startLevel != null ? startLevel : "10");
        }
    }

    /**
     * Return the startup mode
     * @return The startup mode
     */
    public StartupMode getMode() {
        return this.mode;
    }

    /**
     * Is the incremental startup enabled?
     */
    public boolean isIncrementalStartupEnabled() {
        return this.incrementalStartupEnabled;
    }

    /**
     * Return the target start level.
     * @return Target start level
     */
    public long getTargetStartLevel() {
        return this.targetStartLevel;
    }

    /**
     * Detect the startup mode by comparing time stamps
     */
    private StartupMode detectMode(final String osgiStorageDir) {
        final File dataFile = new File(this.confDir, DATA_FILE);
        if (dataFile.exists()) {

            FileReader fis = null;
            try {
                final long selfStamp = this.getSelfTimestamp();
                if (selfStamp > 0) {

                    fis = new FileReader(dataFile);
                    final char[] txt = new char[128];
                    final int len = fis.read(txt);
                    final String value = new String(txt, 0, len);

                    final long storedStamp = Long.parseLong(value);

                    logger.log(Logger.LOG_INFO, String.format("Stored startup timestamp: %s", storedStamp));

                    return (storedStamp >= selfStamp ? StartupMode.RESTART : StartupMode.UPDATE);
                }

            } catch (final NumberFormatException nfe) {
                // probably still the old value, fallback to assume not
                // installed
                return StartupMode.RESTART;

            } catch (final IOException ioe) {
                logger.log(Logger.LOG_ERROR,
                    "IOException during reading of installed flag.", ioe);

            } finally {
                if (fis != null) {
                    try { fis.close(); } catch (IOException ignore) {}
                }
            }
        } else {
            // check for old data file
            // this is a little bit hacky as we have to directly look into
            // the Apache Felix bundle cache. However, as we know that older
            // versions did use Felix this is fine.
            final File felixDir = new File(osgiStorageDir);
            final File oldFile = new File(felixDir, OLD_DATA_FILE);
            if ( oldFile.exists() ) {
                // this is an update - remove old file
                oldFile.delete();
                return StartupMode.UPDATE;
            }
        }
        // not installed yet - fallback
        return StartupMode.INSTALL;
    }

    /**
     * Get the time stamp of a class through its url classloader (if possible)
     */
    long getTimeStampOfClass(final Class<?> clazz, final long selfStamp) {
        long timeStamp = selfStamp;
        final ClassLoader loader = clazz.getClassLoader();
        if (loader instanceof URLClassLoader) {
            @SuppressWarnings("resource")
            final URLClassLoader urlLoader = (URLClassLoader) loader;
            final URL[] urls = urlLoader.getURLs();
            if (urls.length > 0) {
                final URL url = urls[0];
                try {
                    final long stamp = urls[0].openConnection().getLastModified();
                    if ( stamp > selfStamp ) {
                        logger.log(Logger.LOG_INFO, String.format("Newer timestamp for %s from %s : %s", clazz.getName(), url, selfStamp));
                        timeStamp = stamp;
                    }
                } catch (final IOException ignore) {}
            }
        }
        return timeStamp;
    }

    /**
     * Returns the time stamp of JAR file from which this class has been loaded
     * or -1 if the timestamp cannot be resolved.
     * <p>
     * This method assumes that the ClassLoader of this class is an
     * URLClassLoader and that the first URL entry of this class loader is the
     * JAR providing this class. This is in fact true as the URLClassLoader has
     * been created by the launcher from the launcher JAR file.
     *
     * @return The last modification time stamp of the launcher JAR file or -1
     *         if the class loader of this class is not an URLClassLoader or the
     *         class loader has no URL entries. Both situations are not really
     *         expected.
     * @throws IOException If an error occurs reading accessing the last
     *             modification time stamp.
     */
    private long getSelfTimestamp() {

        // the time stamp of the launcher jar and the bootstrap jar
        long selfStamp = this.getTimeStampOfClass(this.getClass(), -1);
        selfStamp = this.getTimeStampOfClass(LaunchpadContentProvider.class, selfStamp);

        // check whether any bundle is younger than the launcher jar
        final File[] directories = this.startupDir.listFiles(DirectoryUtil.DIRECTORY_FILTER);
        if ( directories != null ) {
            for (final File levelDir : directories) {

                // iterate through all files in the startlevel dir
                final File[] jarFiles = levelDir.listFiles(DirectoryUtil.BUNDLE_FILE_FILTER);
                if ( jarFiles != null ) {
                    for (final File bundleJar : jarFiles) {
                        if (bundleJar.lastModified() > selfStamp) {
                            selfStamp = bundleJar.lastModified();
                            logger.log(Logger.LOG_INFO, String.format("Newer timestamp from %s : %s", bundleJar, selfStamp));
                        }
                    }
                }
            }
        }

        logger.log(Logger.LOG_INFO, String.format("Final self timestamp: %s.", selfStamp));

        // return the final stamp (may be -1 if launcher jar cannot be checked
        // and there are no bundle jar files)
        return selfStamp;
    }

    /**
     * Set the finished installation marker.
     */
    public void markInstalled() {
        final File dataFile = new File(this.confDir, DATA_FILE);
        try {
            this.confDir.mkdirs();
            final FileWriter fos = new FileWriter(dataFile);
            try {
                fos.write(String.valueOf(System.currentTimeMillis()));
            } finally {
                try { fos.close(); } catch (final IOException ignore) {}
            }
        } catch (final IOException ioe) {
            logger.log(Logger.LOG_ERROR,
                "IOException during writing of installed flag.", ioe);
        }
    }
}
