package com.atlassian.stash.internal.repository.sync.dao.v1;

import com.atlassian.activeobjects.external.ActiveObjects;
import com.atlassian.bitbucket.ao.AbstractTruncateColumnSubtask;
import com.atlassian.bitbucket.server.ApplicationPropertiesService;
import com.atlassian.stash.internal.repository.sync.dao.v0.AoRejectedRefV0;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import net.java.ao.Query;
import net.java.ao.schema.StringLength;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import static com.atlassian.stash.internal.repository.sync.dao.v0.AoRejectedRefV0.*;

public class MigrateRejectedRefToV1Subtask extends AbstractTruncateColumnSubtask<AoRejectedRefV0> {
    private static final String TABLE_NAME = "REJECTED_REF";

    public MigrateRejectedRefToV1Subtask(ApplicationPropertiesService applicationPropertiesService) {
        super(applicationPropertiesService, StringLength.MAX_LENGTH, TABLE_NAME, AoRejectedRefV0.class);
    }

    @Override
    protected List<String> getColumnNames() {
        return ImmutableList.of(REF_DISPLAY_ID_COLUMN, REF_ID_COLUMN, REPOSITORY_ID_COLUMN, STATE_COLUMN);
    }

    @Override
    protected List<String> getRowValues(AoRejectedRefV0 row) {
        return ImmutableList.of(
                row.getRefDisplayId(),
                row.getRefId(),
                String.valueOf(row.getRepositoryId()),
                String.valueOf(row.getState()));
    }

    @Override
    protected List<AoRejectedRefV0> selectRowsToProcess(ActiveObjects ao, int pageSize) {

        AoRejectedRefV0[] result = ao.find(AoRejectedRefV0.class, Query
                .select()
                .where(Joiner.on(" OR ").join(
                        columnLengthViolatesLimitClause(REF_DISPLAY_ID_COLUMN, ao),
                        columnLengthViolatesLimitClause(REF_ID_COLUMN, ao)))
                .limit(pageSize));

        return result == null ? Collections.emptyList() : Arrays.asList(result);
    }

    @Override
    protected void truncateRowData(AoRejectedRefV0 row) {
        row.setRefDisplayId(truncateLongValue(row.getRefDisplayId()));
        row.setRefId(truncateLongValue(row.getRefId()));
    }
}
