/*
 * 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.ace.configurator.useradmin.task;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Dictionary;
import java.util.Properties;

import org.apache.ace.repository.Repository;
import org.apache.ace.repository.ext.BackupRepository;
import org.apache.ace.repository.ext.CachedRepository;
import org.apache.ace.repository.ext.impl.CachedRepositoryImpl;
import org.apache.ace.repository.ext.impl.FilebasedBackupRepository;
import org.apache.ace.resourceprocessor.useradmin.UserAdminConfigurator;
import org.apache.felix.dm.Component;
import org.apache.felix.dm.DependencyManager;
import org.osgi.framework.BundleContext;
import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.cm.ManagedService;
import org.osgi.service.log.LogService;

/**
 * UpdateUserAdminTask processes the contents of a repository containing
 * an XML description of the users that should be present in this system's
 * user admin.<br>
 * <br>
 * From the first run on, this task will keep a local copy of the user repository,
 * so login can happen when the server is offline.
 */
public class UpdateUserAdminTask implements Runnable, ManagedService {
    /**
     * The UpdateUserAdminTask is also used as its taskName for the scheduler.
     */
    public static final String PID = UpdateUserAdminTask.class.getName();

    public static final String KEY_REPOSITORY_LOCATION = "repositoryLocation";
    public static final String KEY_REPOSITORY_CUSTOMER = "repositoryCustomer";
    public static final String KEY_REPOSITORY_NAME = "repositoryName";

    private static final String FILE_ROOT = "userrepositories";
    private static final String VERSION = "version";

    // Will by injected by Dependency Manager...
    private volatile UserAdminConfigurator m_configurator;
    private volatile LogService m_log;
    private volatile BundleContext m_context;

    private CachedRepository m_repo;
    private BackupRepository m_backup;
    private String m_repoFilter;
    private File m_properties;
    
    /**
     * Called by Dependency Manager upon initialization of this component.
     * <p>
     * Due to the dependency on the configuration; the {@link #updated(Dictionary)} method is already called!
     * </p>
     * 
     * @param comp this component, cannot be <code>null</code>.
     */
    public void init(Component comp) {
        final DependencyManager dm = comp.getDependencyManager();
        // Add the required dependency to the remote repository...
        comp.add(dm.createServiceDependency()
            .setService(Repository.class, m_repoFilter)
            .setCallbacks("addRepo", "removeRepo")
            .setInstanceBound(true)
            .setRequired(true)
            );
    }

    /**
     * Checks whether there are updates to the remote repository, and if so, updates the users' backend with its contents.
     * 
     * @see java.lang.Runnable#run()
     */
    public void run() {
        try {
            if (!m_repo.isCurrent()) {
                m_configurator.setUsers(m_repo.checkout(true));
                m_log.log(LogService.LOG_DEBUG, "UpdateUserAdminTask updates to a new version: " + m_repo.getMostRecentVersion());
                saveVersion(m_properties, m_repo.getMostRecentVersion());
            }
        }
        catch (IOException e) {
            // If anything went wrong, this means the remote repository is not available;
            // this also means the UserAdmin is left undisturbed.
        	m_log.log(LogService.LOG_WARNING, "Error running update UserAdmin task.", e);
        }
    }

    /**
     * Called by Dependency Manager upon starting of this component.
     * 
     * @param comp this component, cannot be <code>null</code>.
     */
    public void start(Component comp) {
        try {
            // Try to read the server data
            m_configurator.setUsers(m_repo.checkout(true));
        }
        catch (IOException e) {
            try {
                m_log.log(LogService.LOG_DEBUG, "UpdateUserAdminTask failed to load remote data; falling back to local data.");
                // If reading remote fails, try to set whatever we have locally
                m_configurator.setUsers(m_repo.getLocal(true));
            }
            catch (IOException e2) {
                // No problem, now we just have an empty user admin...
                m_log.log(LogService.LOG_DEBUG, "UpdateUserAdminTask failed to load local data.");
            }
        }
    }

    public void updated(Dictionary dict) throws ConfigurationException {
        if (dict != null) {
            String customer = (String) dict.get(KEY_REPOSITORY_CUSTOMER);
            if (customer == null) {
                throw new ConfigurationException(KEY_REPOSITORY_CUSTOMER, "Property missing.");
            }
            String name = (String) dict.get(KEY_REPOSITORY_NAME);
            if (name == null) {
                throw new ConfigurationException(KEY_REPOSITORY_NAME, "Property missing.");
            }

            String fileRoot = FILE_ROOT + File.separator + customer + File.separator + name + File.separator;

            File local = getFile(fileRoot + "local");
            File backup = getFile(fileRoot + "backup");
            m_backup = new FilebasedBackupRepository(local, backup);
            
            m_properties = getFile(fileRoot + "properties");
            
            m_repoFilter = "(&(customer=" + customer + ")(name=" + name + "))";
        }
    }

    /**
     * Creates the cached repository when given a remote repository.
     * 
     * @param remoteRepo the remote repository to add, cannot be <code>null</code>.
     */
    final void addRepo(Repository remoteRepo) {
        m_repo = new CachedRepositoryImpl(remoteRepo, m_backup, loadVersion(m_properties));
    }

    /**
     * Removes the cached repository when given a remote repository.
     * 
     * @param remoteRepo the remote repository to remove, cannot be <code>null</code>.
     */
    final void removeRepo(Repository remoteRepo) {
        m_repo = null;
    }

    private File getFile(String name) {
        File result = m_context.getDataFile(name);
        if (!result.exists()) {
            result.getParentFile().mkdirs();
            try {
                if (!result.createNewFile()) {
                    m_log.log(LogService.LOG_ERROR, "Error creating new file " + name);
                }
            }
            catch (IOException e) {
                m_log.log(LogService.LOG_ERROR, "Error creating new file " + name, e);
            }
        }
        return result;
    }

    /**
     * Loads the most recent version from the given properties file.
     */
    private long loadVersion(File propertiesfile) {
        long result = CachedRepositoryImpl.UNCOMMITTED_VERSION;
        try {
            Properties props = new Properties();
            props.loadFromXML(new FileInputStream(propertiesfile));
            result = Long.parseLong((String) props.get(VERSION));
        }
        catch (IOException ioe) {
            // We have no data; no problem.
        }
        return result;
    }

    /**
     * Saves the most recent version to the given properties file.
     */
    private void saveVersion(File properties, Long version) {
        Properties props = new Properties();
        props.put(VERSION, version.toString());
        try {
            FileOutputStream fileOutputStream = new FileOutputStream(properties);
            props.storeToXML(fileOutputStream, null);
        }
        catch (IOException e) {
            m_log.log(LogService.LOG_ERROR, "UpdateUserAdminTask failed to save local version number.");
        }
    }
}