/*
 * Copyright (C) 2005 - 2011 Jaspersoft Corporation. All rights reserved.
 * http://www.jaspersoft.com.
 *
 * Unless you have purchased  a commercial license agreement from Jaspersoft,
 * the following license terms  apply:
 *
 * This program is free software: you can redistribute it and/or  modify
 * it under the terms of the GNU Affero General Public License  as
 * published by the Free Software Foundation, either version 3 of  the
 * License, or (at your option) any later version.
 *
 * This program 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 Affero  General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public  License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

package com.jaspersoft.jasperserver.war.themes.test;

import com.jaspersoft.jasperserver.api.common.domain.ExecutionContext;
import com.jaspersoft.jasperserver.api.common.domain.impl.ExecutionContextImpl;
import com.jaspersoft.jasperserver.api.metadata.common.domain.FileResource;
import com.jaspersoft.jasperserver.api.metadata.common.domain.Folder;
import com.jaspersoft.jasperserver.api.metadata.common.domain.client.FolderImpl;
import com.jaspersoft.jasperserver.api.metadata.common.service.RepositoryService;
import com.jaspersoft.jasperserver.api.metadata.user.domain.ObjectPermission;
import com.jaspersoft.jasperserver.api.metadata.user.domain.Role;
import com.jaspersoft.jasperserver.api.metadata.user.domain.Tenant;
import com.jaspersoft.jasperserver.api.metadata.user.service.ObjectPermissionService;
import com.jaspersoft.jasperserver.api.metadata.user.service.TenantService;
import com.jaspersoft.jasperserver.util.test.BaseJasperServerTest;
import com.jaspersoft.jasperserver.war.common.JasperServerUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.acl.basic.SimpleAclEntry;
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;

import java.io.*;
import java.util.Date;
import java.util.Properties;

/**
 * @author asokolnikov
 */
public class ThemeTest extends BaseJasperServerTest {

    private static final Log log = LogFactory.getLog(ThemeTest.class);

    public ThemeTest() {
        setAutowireMode(AUTOWIRE_BY_NAME);
    }

    public ThemeTest(String name) {
        super(name);
        setAutowireMode(AUTOWIRE_BY_NAME);
    }

    public void testAddDefaultTheme() throws Exception {

        // Clean up
        log.warn("Deleting folder : /themes");
        try {
            getRepositoryService().deleteFolder(null, "/themes");
        } catch (Exception ex) {}

        log.warn("Importing Themes...");

        InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("theme_files_list.txt");
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));

        String filePath = null;
        getOrCreateFolder("/", "themes", "Themes");

        // add theme resources
        while ((filePath = reader.readLine()) != null) {
            // filePath looks like "themes/themeName/styleOrImage.css"
            //log.warn("Importing the file : " + filePath);
            InputStream fileInputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(filePath);
            processThemeFile(filePath, fileInputStream);
            fileInputStream.close();
        }

        reader.close();

        // apply permissions
        // /themes/default folder needs be R/O for EVERYONE, no exclusions
        Role adminRole = getOrCreateRole(administratorRoleName);
        ObjectPermission objPerm = createObjectPermission("/themes/default", adminRole, SimpleAclEntry.READ);
        ExecutionContext executionContext = JasperServerUtil.getExecutionContext();
        executionContext.getAttributes().add(ObjectPermissionService.PRIVILEGED_OPERATION);
        getObjectPermissionService().putObjectPermission(executionContext, objPerm);
    }

    protected Folder getOrCreateFolder(String baseFolderURI, String name, String label) {
        Folder folder = getRepositoryService().getFolder(null, baseFolderURI + "/" + name);
        if (folder == null) {
            folder = new FolderImpl();
            folder.setName(name);
            folder.setLabel(label);
            Date now = new Date();
            folder.setCreationDate(now);
            folder.setUpdateDate(now);
            folder.setParentFolder(baseFolderURI);
            log.warn("creating folder : " + folder.getURIString());
            getRepositoryService().saveFolder(null, folder);
        }
        return folder;
    }

    protected Folder getOrCreateFolder(String baseFolderURI, String name) {
        return getOrCreateFolder(baseFolderURI, name, name);
    }

    protected void processThemeFile(String filePath, InputStream fileInputStream) throws Exception {
        int length = fileInputStream.available();
        byte[] data = new byte[length];
        int off = 0;
        while ( (off += fileInputStream.read(data, off, length - off)) < length ) {};

        String[] pathParts = filePath.split("/");
        Folder parentFolder = null;
        String baseFolderURI = "";
        for (int i = 0; i < pathParts.length - 1; i++) {
            if (parentFolder != null) {
                baseFolderURI = parentFolder.getURIString();
            }
            parentFolder = getOrCreateFolder(baseFolderURI, pathParts[i]);
        }

        String fileName = pathParts[pathParts.length - 1];
        FileResource fileResource = (FileResource) getRepositoryService().newResource(null, FileResource.class);
        fileResource.setName(fileName);
        fileResource.setLabel(fileName);
        fileResource.setParentFolder(parentFolder);
        Date now = new Date();
        fileResource.setCreationDate(now);
        fileResource.setUpdateDate(now);
        fileResource.setData(data);
        String type = (fileName.toUpperCase().endsWith(".CSS")) ? FileResource.TYPE_CSS : FileResource.TYPE_IMAGE;
        fileResource.setFileType(type);

        log.debug("creating file : " + fileResource.getURIString());
        getRepositoryService().saveResource(null, fileResource);

    }

    protected void onTearDown() {

		/*
		 * Remove repository objects that are not samples in the released product
		 * (ie. objects that users see after installing the application)
		 */
	}

}
