package ru.yandex.qe.dispenser.domain.dao.project.role;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.annotation.ParametersAreNonnullByDefault;

import ru.yandex.qe.dispenser.domain.ProjectRole;
import ru.yandex.qe.dispenser.domain.dao.SqlDaoBase;

@ParametersAreNonnullByDefault
public class SqlProjectRoleDao extends SqlDaoBase implements ProjectRoleDao {

    private static final String GET_ALL_QUERY = "SELECT id, key, abc_role_sync_type, abc_role_id FROM project_role";
    private static final String INSERT_ROLE_QUERY = "INSERT INTO project_role (key, abc_role_sync_type, abc_role_id) VALUES (:key, CAST (:abcRoleSyncType AS abc_role_sync_type), :abcRoleId)";
    private static final String CLEAR_QUERY = "TRUNCATE TABLE project_role CASCADE";

    @Override
    public Set<ProjectRole> getAll() {
        return jdbcTemplate.queryForSet(GET_ALL_QUERY, this::toProjectRole);
    }

    @Override
    public ProjectRole create(final ProjectRole role) {
        final long id = jdbcTemplate.insert(INSERT_ROLE_QUERY, toInsertParams(role));
        role.setId(id);
        return role;
    }

    @Override
    public void clear() {
        jdbcTemplate.update(CLEAR_QUERY);
    }

    private ProjectRole toProjectRole(final ResultSet rs, final int ignored) throws SQLException {
        final ProjectRole projectRole = new ProjectRole(
                rs.getString("key"),
                ProjectRole.AbcRoleSyncType.valueOf(rs.getString("abc_role_sync_type")),
                getLong(rs, "abc_role_id")
        );
        projectRole.setId(rs.getLong("id"));
        return projectRole;
    }

    private Map<String, ?> toInsertParams(final ProjectRole role) {
        final HashMap<String, Object> params = new HashMap<>();

        params.put("key", role.getKey());
        params.put("abcRoleSyncType", role.getAbcRoleSyncType().name());
        params.put("abcRoleId", role.getAbcRoleId());

        return params;
    }

}
