/*
 * (c) 2021 Pluto Inc.
 */
package tv.pluto;

import static tv.pluto.ip.dal.samsungchannelproperty.SamsungChannelProperties.SamsungChannelProperty;

import io.qameta.allure.Description;
import io.qameta.allure.TmsLink;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import tv.pluto.core.BaseTest;
import tv.pluto.grpc.samsung_channel_properties.SamsungChannelPropertiesClient;
import tv.pluto.mongo.entities.samsungchannelproperties.SamsungChannelProperties;
import tv.pluto.mongo.utils.SamsungChannelPropertiesUtils;
import tv.pluto.utils.CommonUtils;

public class SamsungChannelPropertiesTestSuite extends BaseTest {
  private SamsungChannelPropertiesClient samsungChannelPropertiesClient;
  private SamsungChannelPropertiesUtils samsungChannelPropertiesUtils;

  @BeforeClass(alwaysRun = true)
  private void setUp() {
    samsungChannelPropertiesUtils = new SamsungChannelPropertiesUtils();

    // Create a ChannelsClient using the in-process channel;
    samsungChannelPropertiesClient =
        new SamsungChannelPropertiesClient(grpcChannelManager.getChannel());
  }

  @Test
  @Description("GetDocuments")
  @TmsLink("28501290")
  public void C28501290_TEST() {
    List<SamsungChannelProperties> mongoProperties = samsungChannelPropertiesUtils.getDocuments(0);
    List<SamsungChannelProperties> grpcProperties = new ArrayList<>();

    Iterator<SamsungChannelProperty> properties = samsungChannelPropertiesClient.getDocuments();

    while (properties.hasNext()) {
      grpcProperties.add(
          samsungChannelPropertiesUtils.mapGrpcObjectToPojo(
              properties.next(), SamsungChannelProperties.class));
    }

    mongoProperties.sort(Comparator.comparing(SamsungChannelProperties::getId));
    grpcProperties.sort(Comparator.comparing(SamsungChannelProperties::getId));

    Assert.assertEquals(mongoProperties, grpcProperties);
  }

  @Test
  @Description("CFeedsSyncAllIds - stream returns CFEEDS stream of SamsungChannelProperties ids")
  @TmsLink("28501299")
  public void C28501299_TEST() {
    Iterator<?> cFeedsSyncAllIds =
        samsungChannelPropertiesClient.getCFeedsResponse(null, null, null, "cFeedsSyncAllIds");
    List<String> listCFeedsSyncAllIds =
        CommonUtils.iteratorToList(cFeedsSyncAllIds).stream()
            .map(
                o ->
                    ((tv.pluto.ip.dal.samsungchannelproperty.SamsungChannelProperties.Id) o)
                        .getId())
            .sorted()
            .collect(Collectors.toList());
    List<String> mongoIds =
        samsungChannelPropertiesUtils.getListOfAllObjects().stream()
            .map(o -> ((SamsungChannelProperties) o).getId())
            .sorted()
            .collect(Collectors.toList());

    Assert.assertTrue(listCFeedsSyncAllIds.size() > 0);
    Assert.assertTrue(CommonUtils.isTwoListsEqual(listCFeedsSyncAllIds, mongoIds));
  }

  @Test
  @Description("cFeedsSyncDocuments - last_run_at")
  @TmsLink("28501300")
  public void C28501300_TEST() {
    LocalDateTime lastRunTime = LocalDateTime.parse("2019-02-08T09:26:19.367");
    Iterator<?> cFeedsSyncAllIds =
        samsungChannelPropertiesClient.getCFeedsResponse(
            null, lastRunTime + "Z", null, "cFeedsSyncDocuments");

    List<?> listSamsungDocs = CommonUtils.iteratorToList(cFeedsSyncAllIds);
    List<SamsungChannelProperties> grpcSamsungCategories =
        samsungChannelPropertiesUtils.mapGrpcObjectsToPojo(
            listSamsungDocs, SamsungChannelProperties.class);

    List<SamsungChannelProperties> mongoListSamsungProperties =
        samsungChannelPropertiesUtils.getDocumentsForFeedsSyncStartTime(lastRunTime).stream()
            .map(o -> ((SamsungChannelProperties) o))
            .collect(Collectors.toList());

    grpcSamsungCategories.sort(Comparator.comparing(SamsungChannelProperties::getId));
    mongoListSamsungProperties.sort(Comparator.comparing(SamsungChannelProperties::getId));

    List<String> listIdsPartners =
        grpcSamsungCategories.stream()
            .map(SamsungChannelProperties::getId)
            .collect(Collectors.toList());
    List<String> listIdsMongoPartners =
        mongoListSamsungProperties.stream()
            .map(SamsungChannelProperties::getId)
            .collect(Collectors.toList());

    Assert.assertTrue(grpcSamsungCategories.size() > 0);
    Assert.assertEquals(listIdsPartners, listIdsMongoPartners);
  }

  @Test(
      expectedExceptions = RuntimeException.class,
      expectedExceptionsMessageRegExp = NOT_FOUND_MESSAGE)
  @Description("cFeedsSyncDocuments - last_run_at future time")
  @TmsLink("28501301")
  public void C28501301_TEST() {
    String futureTime = CommonUtils.localDateTimeStringPlusDays(10);
    samsungChannelPropertiesClient
        .getCFeedsResponse(null, futureTime, null, "cFeedsSyncDocuments")
        .next();
  }
}
