/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 2013 Bull S.A.S.
 * Contact: jonas-team@ow2.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */
package org.ow2.jonas.addon.test;

import org.mockito.Mockito;
import org.osgi.framework.BundleContext;
import org.ow2.jonas.addon.deploy.api.deployable.IAddonDeployable;
import org.ow2.jonas.addon.deploy.api.deployer.IAddonDeployer;
import org.ow2.jonas.addon.deploy.api.deployer.IAddonDeployerLog;
import org.ow2.jonas.addon.deploy.api.deployer.IConfDeployer;
import org.ow2.jonas.addon.deploy.impl.deployer.AddonDeployerImpl;
import org.ow2.jonas.addon.deploy.impl.deployer.ConfDeployerImpl;
import org.ow2.jonas.addon.deploy.impl.helper.service.AddonDeployableAnalyserComponent;
import org.ow2.jonas.addon.deploy.impl.util.AddonDeployerLog;
import org.ow2.jonas.addon.deploy.impl.util.AddonUtil;
import org.ow2.jonas.lib.bootstrap.JProp;
import org.ow2.jonas.lib.work.DeployerLog;
import org.ow2.jonas.management.ServiceManager;
import org.ow2.jonas.properties.ServerProperties;
import org.ow2.jonas.workcleaner.IDeployerLog;
import org.ow2.util.archive.api.IArchive;
import org.ow2.util.archive.impl.ArchiveManager;
import org.ow2.util.ee.deploy.api.deployable.IDeployable;
import org.ow2.util.ee.deploy.api.deployer.IDeployerManager;
import org.ow2.util.ee.deploy.api.helper.IDeployableHelper;
import org.ow2.util.ee.deploy.impl.helper.DeployableAnalyserTracker;
import org.ow2.util.ee.deploy.impl.helper.DeployableHelperComponent;
import org.ow2.util.file.FileUtils;
import org.ow2.util.plan.repository.api.IRepositoryManager;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import static org.mockito.Mockito.mock;

/**
 *  Template use to test the module
 *  @author Jeremy Cazaux
 */
public class BaseTestCase {

    /**
     * Maven output directory
     */
    public static final File BUILD_OUTPUT_DIR = new File("target");

    /**
     * Directory which provide addons
     */
    public static final File ADDON_DIR = new File(BUILD_OUTPUT_DIR, "addons");

    /**
     * JOnAS ROOT directory
     */
    public static final File JONAS_ROOT= new File(BUILD_OUTPUT_DIR, "jonas-root");

    /**
     * JOnAS ROOT system property
     */
    public static final String JONAS_ROOT_SYSTEM_PROPERTY = "jonas.root";

    /**
     * JOnAS Base system property
     */
    public static final String JONAS_BASE_SYSTEM_PROPERTY = "jonas.base";

    /**
     * The {@link org.ow2.util.ee.deploy.api.helper.IDeployableHelper}
     */
    protected IDeployableHelper deployableHelper;

    /**
     * The {@link org.ow2.jonas.properties.ServerProperties}
     */
    protected ServerProperties serverProperties;

    /**
     * The {@link org.ow2.jonas.addon.deploy.api.deployer.IAddonDeployerLog}
     */
    protected IAddonDeployerLog deployerLog;

    /**
     * The {@link org.ow2.jonas.workcleaner.IDeployerLog}
     */
    protected IDeployerLog workCleanerLog;

    /**
     * The {@link org.osgi.framework.BundleContext}
     */
    protected BundleContext bundleContext;

    /**
     * The {@link org.ow2.util.ee.deploy.api.deployer.IDeployerManager}
     */
    protected IDeployerManager deployerManager;

    /**
     * The {@link IConfDeployer}
     */
    protected IConfDeployer confDeployer;

    /**
     * The {@link org.ow2.jonas.management.ServiceManager}
     */
    protected ServiceManager serviceManager;

    /**
     * The {@link org.ow2.util.plan.repository.api.IRepositoryManager}
     */
    protected IRepositoryManager repositoryManager;

    /**
     * The {@link org.ow2.jonas.addon.deploy.api.deployer.IAddonDeployer}
     */
    protected IAddonDeployer deployer;

    /**
     * Init
     */
    @BeforeClass
    public void init() throws Exception {

        //init the list of IDeployableAnalyser
        List<Object> deployableAnalyzerList = new ArrayList<Object>();
        deployableAnalyzerList.add(new AddonDeployableAnalyserComponent());

        //init the DeployableAnalyzerTracker
        DeployableAnalyserTracker deployableAnalyserTracker = mock(DeployableAnalyserTracker.class);
        Mockito.when(deployableAnalyserTracker.getServices()).thenReturn(deployableAnalyzerList.toArray());

        //init the IDeployableHelper
        this.deployableHelper = new DeployableHelperComponent(deployableAnalyserTracker);

        //update system properties
        System.getProperties().setProperty(JONAS_ROOT_SYSTEM_PROPERTY, JONAS_ROOT.getAbsolutePath());
        System.getProperties().setProperty(JONAS_BASE_SYSTEM_PROPERTY, JONAS_ROOT.getAbsolutePath());

        //Instanciate ServerProperties
        this.serverProperties = JProp.getInstance();

        //instanciate deployer logs
        this.deployerLog = new AddonDeployerLog(getLogFile());
        this.workCleanerLog = new DeployerLog(getWorkcleanerLogFile());

        //mock the bundle context,deployer manager, repository manager and the service manager
        this.bundleContext = mock(BundleContext.class);
        this.deployerManager = mock(IDeployerManager.class);
        this.serviceManager = mock(ServiceManager.class);
        this.repositoryManager = mock(IRepositoryManager.class);

        this.confDeployer = new ConfDeployerImpl(this.bundleContext);

        //get a new instance of the addon deployer
        this.deployer = getAddonDeployerInstance();

        //register the deployer on the deployer manager
        this.deployerManager.register(this.deployer);
    }

    /**
     * @return a new instance of the {@link IAddonDeployer} object
     */
    protected IAddonDeployer getAddonDeployerInstance() {
        return new AddonDeployerImpl(this.serverProperties, this.deployableHelper, this.deployerLog,
                this.deployerManager, this.bundleContext,  this.serviceManager, this.workCleanerLog,
                this.repositoryManager, this.confDeployer);
    }

    public IAddonDeployable getDeployable(final File file)throws Exception {
        IArchive archive = ArchiveManager.getInstance().getArchive(file);
        IDeployable<?> deployable = this.deployableHelper.getDeployable(archive);
        return IAddonDeployable.class.cast(deployable);
    }

    @AfterMethod
    public void after() throws Exception {
        File file = new File(JONAS_ROOT, "work");
        if (file.exists()) {
            FileUtils.delete(file);
        }
        FileUtils.delete(new File(AddonUtil.JONAS_ADDONS_DIRECTORY));

        this.repositoryManager = mock(IRepositoryManager.class);
        this.deployerLog = new AddonDeployerLog(getLogFile());
        this.workCleanerLog = new DeployerLog(getWorkcleanerLogFile());
        this.deployerManager = mock(IDeployerManager.class);
        this.confDeployer = new ConfDeployerImpl(this.bundleContext);
        this.deployer = getAddonDeployerInstance();
    }

    private File getLogFile() throws Exception {
        File logFile = new File(AddonUtil.getAddonLogFile(this.serverProperties));
        if (!logFile.exists()) {
            logFile.getParentFile().mkdirs();
            logFile.createNewFile();
        }
        return logFile;
    }

    private File getWorkcleanerLogFile() throws Exception {
        File workCleanerLogFile = new File(AddonUtil.getWorkCleanerLogFile(this.serverProperties));
        if (!workCleanerLogFile.exists()) {
            workCleanerLogFile.getParentFile().mkdirs();
            workCleanerLogFile.createNewFile();
        }
        return workCleanerLogFile;
    }
}

