/*
 * 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.api.metadata.view.service.impl;

import com.jaspersoft.jasperserver.api.common.domain.impl.ExecutionContextImpl;
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.domain.User;
import com.jaspersoft.jasperserver.api.metadata.user.domain.client.TenantImpl;
import com.jaspersoft.jasperserver.api.metadata.user.service.TenantService;
import com.jaspersoft.jasperserver.api.metadata.user.service.UserAuthorityService;
import junit.textui.TestRunner;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UserDetailsService;
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;

import javax.naming.NamingException;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;

/**
 * @author swood
 * @version $Id: TenantServiceTest.java 19930 2010-12-11 15:17:19Z tmatyashovsky $
 */
public class TenantServiceTest extends AbstractDependencyInjectionSpringContextTests {

    final static int ORG_COUNT = 5;
    final static String ID_PREFIX = "test_org_";
    final static String ALIAS_PREFIX = "TO ";
    final static String NAME_PREFIX = "Test Organization ";
    final static String URI_PREFIX = "/";
    final static String FOLDER_UIR_PREFIX = "/" + TenantService.ORGANIZATIONS;

    List<String> deleteList;
    Properties jdbcProps;
    UserAuthorityService userAuthorityService;
    TenantService tenantService;

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

    public static void main(String[] args) {
        TestRunner.run(TenantServiceTest.class);
    }

    protected String[] getConfigLocations() {
        try {
            loadJdbcProps();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        // metadata.additionalSettings=hibernateRepositoryAdditionalSettings.xml

        if (jdbcProps.getProperty("metadata.additionalSettings") == null) {
            return
                    new String[]{"hibernateConfig.xml", "userAuthorityService.xml", "viewService.xml", "methodAndObjectSecurity.xml"};
        } else {
            return
                    new String[]{"hibernateConfig.xml", jdbcProps.getProperty("metadata.additionalSettings"), "userAuthorityService.xml", "viewService.xml", "methodAndObjectSecurity.xml"};
        }
    }

    protected Properties loadJdbcProps() throws IOException, FileNotFoundException, NamingException {
        jdbcProps = new Properties();
        String jdbcPropFile = System.getProperty("test.hibernate.jdbc.properties");
        BufferedInputStream is = new BufferedInputStream(new FileInputStream(jdbcPropFile));
        jdbcProps.load(is);
        is.close();
        return jdbcProps;
    }

    protected void onSetUp() throws Exception {
        super.onSetUp();

        tenantService = (TenantService) this.getApplicationContext().getBean("tenantService");

        Tenant root = tenantService.getTenant(new ExecutionContextImpl(), TenantService.ORGANIZATIONS);

        deleteList = new ArrayList<String>();

        for (int i = 1; i <= ORG_COUNT; i++) {
            Tenant t = createTenant(Integer.toString(i), root);
            tenantService.putTenant(null, t);

            deleteList.add(t.getId());

            for (int j = 1; j <= ORG_COUNT; j++) {
                Tenant tt = createTenant(Integer.toString(i) + Integer.toString(j), t);
                tenantService.putTenant(null, tt);

                deleteList.add(tt.getId());
            }

        }
    }

    public void onTearDown() {
        Collections.reverse(deleteList);
        for (String id : deleteList) {
            tenantService.deleteTenant(null, id);
        }
    }

    private Tenant createTenant(String number, Tenant parent) {
        Tenant t = new TenantImpl();

        t.setId(ID_PREFIX + number);
        t.setAlias(ALIAS_PREFIX + number);
        t.setTenantName(NAME_PREFIX + number);
        StringBuilder uri = new StringBuilder();
        StringBuilder fUri = new StringBuilder();

        if (parent != null) {
            t.setParentId(parent.getId());
            uri.append(parent.getTenantUri());
            fUri.append(parent.getTenantFolderUri());
        }

        if (uri.lastIndexOf("/") != uri.length() - 1) {
            uri.append("/");
        }
        if (fUri.lastIndexOf("/") != fUri.length() - 1) {
            fUri.append("/");
        }

        uri.append(t.getId());
        fUri.append(TenantService.ORGANIZATIONS).append("/").append(t.getId());

        t.setTenantUri(uri.toString());
        t.setTenantFolderUri(fUri.toString());

        return t;
    }

    public void testGetTenant() {
        Tenant t = tenantService.getTenant(new ExecutionContextImpl(), TenantService.ORGANIZATIONS);

        assertNotNull(t);
        assertEquals(TenantService.ORGANIZATIONS, t.getId());
    }

    public void testPutTenant() {
        Tenant genTenant = createTenant(Integer.toString(0), null);

        tenantService.putTenant(new ExecutionContextImpl(), genTenant);

        Tenant tenant = tenantService.getTenant(new ExecutionContextImpl(), genTenant.getId());
        assertNotNull(tenant);

        tenantService.deleteTenant(null, tenant.getId());

        assertEquals(genTenant.getId(), tenant.getId());
        assertEquals(genTenant.getTenantName(), tenant.getTenantName());
    }

    public void testDeleteTenant() {
        String id = Integer.toString(1) + Integer.toString(1);

        Tenant genTenant = createTenant(id, null);
        tenantService.deleteTenant(new ExecutionContextImpl(), genTenant.getId());

        Tenant tenant = tenantService.getTenant(new ExecutionContextImpl(), genTenant.getId());
        assertNull(tenant);

        deleteList.remove(genTenant.getId());
    }

    public void testGetAllSubTenantList() {
        assertNotNull(tenantService);

        List tenants = tenantService.getAllSubTenantList(new ExecutionContextImpl(), TenantService.ORGANIZATIONS);

        assertNotNull(tenants);
        assertEquals(31, tenants.size());

        Tenant genTenant = createTenant(Integer.toString(1), null);
        tenants = tenantService.getAllSubTenantList(new ExecutionContextImpl(), genTenant.getId());

        assertNotNull(tenants);
        assertEquals(5, tenants.size());
    }


}