package org.wso2.carbon.is.migration.service.v700.dao;

import org.wso2.carbon.identity.application.common.model.Scope;
import org.wso2.carbon.identity.core.migrate.MigrationClientException;
import org.wso2.carbon.identity.core.util.IdentityDatabaseUtil;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class ScopeDAO {

    private static final String INSERT_SCOPE = "INSERT INTO SCOPE (ID, API_ID, NAME, DISPLAY_NAME, DESCRIPTION, " +
            "TENANT_ID) VALUES (?, ?, ?, ?, ?, ?)";
    private static final String INSERT_SYSTEM_SCOPE = "INSERT INTO SCOPE (ID, API_ID, NAME, DISPLAY_NAME, " +
            "DESCRIPTION) VALUES (?, ?, ?, ?, ?)";
    private static final String GET_SYSTEM_SCOPES = "SELECT NAME FROM SCOPE WHERE TENANT_ID IS NULL";

    /**
     * Insert scope.
     *
     * @param apiId    API ID.
     * @param scopes   List of scopes.
     * @param tenantId Tenant ID.
     * @throws MigrationClientException If an error occurs while inserting the scope.
     */
    public void insertScopes(String apiId, List<Scope> scopes, Integer tenantId)
            throws MigrationClientException {

        String sql;
        if (tenantId != null) {
            sql = INSERT_SCOPE;
        } else {
            sql = INSERT_SYSTEM_SCOPE;
        }
        try (Connection connection = IdentityDatabaseUtil.getDBConnection(false);
             PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
            for (Scope scope : scopes) {
                preparedStatement.setString(1, UUID.randomUUID().toString());
                preparedStatement.setString(2, apiId);
                preparedStatement.setString(3, scope.getName());
                preparedStatement.setString(4, scope.getDisplayName());
                preparedStatement.setString(5, scope.getDescription());
                if (tenantId != null) {
                    preparedStatement.setInt(6, tenantId);
                }
                preparedStatement.addBatch();
            }
            preparedStatement.executeBatch();
        } catch (SQLException e) {
            throw new MigrationClientException("Error while inserting scope.", e);
        }
    }

    public List<String> getAllSystemScopes() throws MigrationClientException {

        try (Connection connection = IdentityDatabaseUtil.getDBConnection(false)) {
            try (PreparedStatement preparedStatement = connection.prepareStatement(GET_SYSTEM_SCOPES)) {
                try (ResultSet resultSet = preparedStatement.executeQuery()) {
                    List<String> scopes = new ArrayList<>();
                    while (resultSet.next()) {
                        scopes.add(resultSet.getString("NAME"));
                    }
                    return scopes;
                }
            }
        } catch (SQLException e) {
            throw new MigrationClientException("Error while retrieving all system scopes.", e);
        }
    }

}
