package tv.pluto;

import static tv.pluto.mongo.utils.MongoUtils.INVALID_ID_VALUE;

import com.plutotv.test.lib.LogUtils;
import io.grpc.StatusRuntimeException;
import io.qameta.allure.Description;
import io.qameta.allure.TmsLink;
import java.util.Arrays;
import java.util.List;
import net.datafaker.Faker;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.testng.asserts.SoftAssert;
import tv.pluto.core.BaseTest;
import tv.pluto.grpc.transcodejobs.TranscodeJobsClient;
import tv.pluto.grpc.transcodejobs.TranscodeUpdateRequest;
import tv.pluto.ip.dal.transcodejobs.TranscodeJobs.TranscodeJob;
import tv.pluto.mongo.entities.transcodejobs.TranscodeJobs;
import tv.pluto.mongo.utils.TranscodeJobsUtils;

public class TranscodeJobsTestSuite extends BaseTest {
  private TranscodeJobsClient transcodeJobsClient;
  private TranscodeJobsUtils transcodeJobsUtils;
  private final List<String> statuses = Arrays.asList("created", "failed", "ready", "submitted");

  @BeforeClass(alwaysRun = true)
  private void setUp() {
    transcodeJobsClient = new TranscodeJobsClient(grpcChannelManager.getChannel());
    transcodeJobsUtils = new TranscodeJobsUtils();
  }

  @Test
  @Description("UpdateTranscodeStatusAndReturnUpdated - update existing job")
  @TmsLink("28501792")
  public void C28501792_TEST() {
    SoftAssert softAssert = new SoftAssert();
    TranscodeJobs transcodeJob = transcodeJobsUtils.getOldestJobWithLibVersion();

    LogUtils.logInfoMessage("TranscodeJob ID for C1151241_TEST = " + transcodeJob.getId());

    TranscodeUpdateRequest transcodeUpdateRequest = new TranscodeUpdateRequest();

    // set query parameters
    transcodeUpdateRequest.setQueryExternalID(transcodeJob.getExternalID());
    transcodeUpdateRequest.setQueryTranscoderName(transcodeJob.getTranscoderName());
    transcodeUpdateRequest.setQueryGteLibVersion(transcodeJob.getLibVersion());

    // set update fields
    transcodeUpdateRequest.setSetStatus(transcodeJobsUtils.getRandomItem(statuses));
    transcodeUpdateRequest.setSetError(new Faker().chuckNorris().fact());
    transcodeUpdateRequest.setSetProgress(new Faker().random().nextInt(1, 100));

    TranscodeJobs grpcResponseTranscodeJob =
        transcodeJobsUtils.mapGrpcObjectToPojo(
            transcodeJobsClient
                .updateTranscodeStatusAndReturnUpdated(transcodeUpdateRequest)
                .getDocument(),
            TranscodeJobs.class);

    TranscodeJobs mongoResponseTranscodeJob =
        transcodeJobsUtils.getDocumentById(grpcResponseTranscodeJob.getId());

    softAssert.assertEquals(mongoResponseTranscodeJob, grpcResponseTranscodeJob);
    softAssert.assertEquals(
        mongoResponseTranscodeJob.getStatus(), transcodeUpdateRequest.getSetStatus());
    softAssert.assertEquals(
        mongoResponseTranscodeJob.getError(), transcodeUpdateRequest.getSetError());
    softAssert.assertEquals(
        mongoResponseTranscodeJob.getProgress(), transcodeUpdateRequest.getSetProgress());
    softAssert.assertAll();
  }

  @Test(
      expectedExceptions = StatusRuntimeException.class,
      expectedExceptionsMessageRegExp =
          "NOT_FOUND: TranscodeJob for requested query not found to be updated")
  @Description("UpdateTranscodeStatusAndReturnUpdated - update existing job")
  @TmsLink("28501793")
  public void C28501793_TEST() {
    TranscodeJobs transcodeJob = transcodeJobsUtils.getOldestJobWithLibVersion();

    TranscodeUpdateRequest transcodeUpdateRequest = new TranscodeUpdateRequest();

    // set query parameters
    transcodeUpdateRequest.setQueryExternalID(INVALID_ID_VALUE);
    transcodeUpdateRequest.setQueryTranscoderName(transcodeJob.getTranscoderName());
    transcodeUpdateRequest.setQueryGteLibVersion(transcodeJob.getLibVersion());

    // set update fields
    transcodeUpdateRequest.setSetStatus(transcodeJobsUtils.getRandomItem(statuses));
    transcodeUpdateRequest.setSetError(new Faker().chuckNorris().fact());
    transcodeUpdateRequest.setSetProgress(new Faker().random().nextInt(1, 100));

    transcodeJobsClient.updateTranscodeStatusAndReturnUpdated(transcodeUpdateRequest);
  }

  @Test
  @Description("UpdateTranscodeStatusAndReturnUpdated - update existing job, with fragments")
  @TmsLink("28501794")
  public void C28501794_TEST() {
    SoftAssert softAssert = new SoftAssert();
    TranscodeJobs transcodeJob = transcodeJobsUtils.getJobWithFragments();

    LogUtils.logInfoMessage("TranscodeJob ID for C1461796_TEST = " + transcodeJob.getId());

    TranscodeUpdateRequest transcodeUpdateRequest = new TranscodeUpdateRequest();

    // set query parameters
    transcodeUpdateRequest.setQueryExternalID(transcodeJob.getExternalID());
    transcodeUpdateRequest.setQueryTranscoderName(transcodeJob.getTranscoderName());
    transcodeUpdateRequest.setQueryGteLibVersion(transcodeJob.getLibVersion());

    // set update fields
    transcodeUpdateRequest.setSetStatus(transcodeJobsUtils.getRandomItem(statuses));
    transcodeUpdateRequest.setSetError(new Faker().chuckNorris().fact());
    transcodeUpdateRequest.setSetProgress(new Faker().random().nextInt(1, 100));

    TranscodeJob grpcUpdatedJob =
        transcodeJobsClient
            .updateTranscodeStatusAndReturnUpdated(transcodeUpdateRequest)
            .getDocument();

    TranscodeJobs grpcResponseTranscodeJob =
        transcodeJobsUtils.mapGrpcObjectToPojo(grpcUpdatedJob, TranscodeJobs.class);

    TranscodeJobs mongoResponseTranscodeJob =
        transcodeJobsUtils.getDocumentById(grpcResponseTranscodeJob.getId());

    softAssert.assertEquals(
        mongoResponseTranscodeJob,
        transcodeJobsUtils.setTranscodes(grpcUpdatedJob, grpcResponseTranscodeJob));
    softAssert.assertEquals(
        mongoResponseTranscodeJob.getStatus(), transcodeUpdateRequest.getSetStatus());
    softAssert.assertEquals(
        mongoResponseTranscodeJob.getError(), transcodeUpdateRequest.getSetError());
    softAssert.assertEquals(
        mongoResponseTranscodeJob.getProgress(), transcodeUpdateRequest.getSetProgress());
    softAssert.assertAll();
  }
}
