/*
 * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). All Rights Reserved.
 *
 * This software is the property of WSO2 LLC. and its suppliers, if any.
 * Dissemination of any information or reproduction of any material contained
 * herein in any form is strictly forbidden, unless permitted by WSO2 expressly.
 * You may not alter or remove any copyright or other notice from copies of this content.
 */
package org.wso2.carbon.is.migration.service.v700.migrator;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.wso2.carbon.identity.core.migrate.MigrationClientException;
import org.wso2.carbon.is.migration.service.Migrator;
import org.wso2.carbon.is.migration.service.v700.service.AssignInternalScopesForRolesService;
import org.wso2.carbon.is.migration.service.v700.service.AssociateTenantToOrgService;
import org.wso2.carbon.is.migration.service.v700.service.CreateSystemAppsInTenantService;
import org.wso2.carbon.is.migration.service.v700.service.IdPRoleToLocalRoleMappingsMigrationService;
import org.wso2.carbon.is.migration.service.v700.service.ManagementAppAPIAuthorizationService;
import org.wso2.carbon.is.migration.service.v700.service.OAuth2ScopeMigrationService;
import org.wso2.carbon.is.migration.service.v700.service.PermissionStringMigrationService;
import org.wso2.carbon.is.migration.service.v700.service.RoleV2MigrationService;
import org.wso2.carbon.is.migration.service.v700.service.SystemAPIResourceCreationService;
import org.wso2.carbon.is.migration.util.Constant;
import org.wso2.carbon.is.migration.util.ReportUtil;

import java.io.IOException;
import java.util.Properties;

import static org.wso2.carbon.is.migration.service.v700.constant.MigratorConstants.SUBSCRIBE_ALL;
import static org.wso2.carbon.is.migration.util.Constant.REPORT_PATH;

public class LegacyToNewRuntimeMigrator extends Migrator {

    private final AssociateTenantToOrgService associateTenantToOrgService = new AssociateTenantToOrgService();
    private final RoleV2MigrationService roleV2MigrationService = new RoleV2MigrationService();
    private final SystemAPIResourceCreationService systemAPIResourceCreationService = new SystemAPIResourceCreationService();
    private final CreateSystemAppsInTenantService createSystemAppsInTenantService = new CreateSystemAppsInTenantService();
    private final ManagementAppAPIAuthorizationService managementAppAPIAuthorizationService = new ManagementAppAPIAuthorizationService();
    private final AssignInternalScopesForRolesService assignInternalScopesForRolesService = new AssignInternalScopesForRolesService();
    private final PermissionStringMigrationService permissionStringMigrationService = new PermissionStringMigrationService();
    private final OAuth2ScopeMigrationService oAuth2ScopeMigrationService = new OAuth2ScopeMigrationService();
    private final IdPRoleToLocalRoleMappingsMigrationService idPRoleToLocalRoleMappingsMigrationService = new IdPRoleToLocalRoleMappingsMigrationService();

    private static final Logger LOG = LoggerFactory.getLogger(LegacyToNewRuntimeMigrator.class);

    @Override
    public void dryRun() throws MigrationClientException {

        LOG.info(Constant.MIGRATION_LOG + "Executing dry run for {}", this.getClass().getName());
        Properties migrationProperties = getMigratorConfig().getParameters();
        String reportPath = (String) migrationProperties.get(REPORT_PATH);
        ReportUtil reportUtil = new ReportUtil(reportPath);
        reportUtil.writeMessage("\n--- Summary of the report ---\n");
        LOG.info(Constant.MIGRATION_LOG + "Started the dry run for {} migration.",
                this.getClass().getName());

        managementAppAPIAuthorizationService.dryRun(reportUtil);
        try {
            reportUtil.commit();
        } catch (IOException e) {
            throw new MigrationClientException("Error occurred when generating the report.",e);
        }
    }

    @Override
    public void migrate() throws MigrationClientException {

        associateTenantToOrgService.execute();
        roleV2MigrationService.execute();
        systemAPIResourceCreationService.execute();
        createSystemAppsInTenantService.execute();

        Properties migrationProperties = getMigratorConfig().getParameters();
        boolean subscribeAllAPIs = Boolean.parseBoolean((String) migrationProperties.get(SUBSCRIBE_ALL));
        managementAppAPIAuthorizationService.execute(subscribeAllAPIs);
        assignInternalScopesForRolesService.execute();
        permissionStringMigrationService.execute();
        oAuth2ScopeMigrationService.execute();
        idPRoleToLocalRoleMappingsMigrationService.execute();
    }
}
