package io.delphi.qa.auto.awsmfrw.tests.slz;

import com.amazonaws.services.s3.model.S3ObjectSummary;
import io.delphi.qa.auto.awsmfrw.common_baby.IsaCommonMethods;
import io.delphi.qa.auto.awsmfrw.common_baby.delphi.aws.EnAwsS3Buckets;
import io.delphi.qa.auto.awsmfrw.common_baby.delphi.aws.EnAwsS3DspConfigs;
import io.delphi.qa.auto.awsmfrw.models.*;
import io.delphi.qa.auto.awsmfrw.models.aws.lm.WpSlzUnitOfWork;
import io.delphi.qa.auto.awsmfrw.models.aws.s3.complete_criteria.S3DspCompleteCriteria;
import io.delphi.qa.auto.awsmfrw.models.aws.s3.dsp_specific_settings.S3DspSpecificSettings;
import io.delphi.qa.auto.awsmfrw.suppliers.DelphiDataContainer;
import org.testng.Assert;
import org.testng.annotations.Test;

import java.util.HashMap;
import java.util.List;
import java.util.Set;

public class S3_UnitTest extends BsSlzTest {

  private final String REPORT_NAME = "amazonadsupported-sme-user-v1";

  @Override
  public String genTestRunId() {
    return IsaCommonMethods.testRunId();
  }

  private WpSlzUnitOfWork getWpSlzUnitOfWork() {
    MlFw_ReportWrapper mlFwReportWrapper =
        new MlFw_ReportWrapper()
            .withDsp(EnDelphiDspItems.AMAZONADSUPPORTED)
            .withLicensor(EnDelphiLicensorItems.SME)
            .withReport(EnDelphiReportItems.USER)
            .withVersion(EnDelphiReportVersionItems.v1);
    WpSlzUnitOfWork wpSlzUnitOfWork = DelphiDataContainer.genNewMlWpUnitOfWork(mlFwReportWrapper);
    wpSlzUnitOfWork.withCompleteCriteriaSet(getDspCompleteCriteria(mlFwReportWrapper).getCompleteCriteria());
    wpSlzUnitOfWork =
        wpSlzUnitOfWork.withCompleteCriteriaSet(
            super.getCustomCompleteCriteriaItem(mlFwReportWrapper, envConfig.whichCompleteCriteria()));
    return wpSlzUnitOfWork;
  }

  @Test
  public void tc001_getDspCompleteCriteria() {
    List<HashMap<String, Object>> s3CompleteCriteriaList =
        delphi
            .aws()
            .s3()
            .getS3Object(
                EnAwsS3Buckets.DELPHI_CONFIG.get(),
                EnAwsS3DspConfigs.DSP_COMPLETE_CRITERIA_KEY.get(),
                new HashMap<>());
    S3DspCompleteCriteria s3DspCompleteCriteria =
        gson.fromJson(
            gson.toJson(s3CompleteCriteriaList.get(0).get("amazonadsupported-sme-activity")),
            S3DspCompleteCriteria.class);
    Assert.assertTrue(s3DspCompleteCriteria.getLicensor().contains("sme"));
  }

  @Test
  public void tc002_getDspSpecificSettings() {
    List<HashMap> s3ObjectList =
        delphi
            .aws()
            .s3()
            .getS3Object(
                EnAwsS3Buckets.DELPHI_CONFIG.get(),
                EnAwsS3DspConfigs.DSP_SPECIFIC_SETTINGS_KEY.get(),
                new HashMap());
    S3DspSpecificSettings dspSpecificSettings =
        gson.fromJson(gson.toJson(s3ObjectList.get(0).get("apple")), S3DspSpecificSettings.class);
    Assert.assertTrue(dspSpecificSettings.getUowActiveDaysLimit() > 0);
  }

  @Test
  public void tc003_getDspConfigKey() {
    Set<S3ObjectSummary> s3ObjectSummaries =
        delphi
            .aws()
            .s3()
            .listS3Objects(
                EnAwsS3Buckets.DELPHI_CONFIG.get(),
                EnAwsS3DspConfigs.DSP_CONFIG_KEY_AUTO_PREFIX.get());
    Assert.assertTrue(true);
  }

  @Test
  public void tc011_listS3Objects() {
    WpSlzUnitOfWork wpSlzUnitOfWork = getWpSlzUnitOfWork();
    String reportPrefix = IsaCommonMethods.buildS3ReportPrefix(wpSlzUnitOfWork);
    delphi.aws().s3().listS3Objects(EnAwsS3Buckets.DELPHI_SME_DATA_ARCHIVE.get(), reportPrefix);
    Assert.assertTrue(true);
  }

  @Test
  public void tc021_deleteS3Object() {
    WpSlzUnitOfWork wpSlzUnitOfWork = getWpSlzUnitOfWork();
    // config key
    String dspConfigKey = EnAwsS3DspConfigs.DSP_CONFIG_KEY_AUTO_PREFIX.get();
    super.uploadCustomDspConfigFile(wpSlzUnitOfWork, super.getTestRunId());
    Set<S3ObjectSummary> dspConfigKeys =
        delphi.aws().s3().listS3Objects(EnAwsS3Buckets.DELPHI_CONFIG.get(), dspConfigKey);
    dspConfigKeys.forEach(delphi.aws().s3()::deleteS3ObjectSummary);
    dspConfigKeys =
        delphi.aws().s3().listS3Objects(EnAwsS3Buckets.DELPHI_CONFIG.get(), dspConfigKey);
    Assert.assertEquals(dspConfigKeys.size(), 0);
    // butch run config
    String batchRunConfigKey = EnAwsS3DspConfigs.BATCH_RUN_CONFIG_KEY_AUTO_PREFIX.get();
    super.uploadCustomButchRunConfig(wpSlzUnitOfWork);
    Set<S3ObjectSummary> batchRunConfigKeys =
        delphi.aws().s3().listS3Objects(EnAwsS3Buckets.DELPHI_CONFIG.get(), batchRunConfigKey);
    batchRunConfigKeys.forEach(delphi.aws().s3()::deleteS3ObjectSummary);
    batchRunConfigKeys =
        delphi.aws().s3().listS3Objects(EnAwsS3Buckets.DELPHI_CONFIG.get(), dspConfigKey);
    Assert.assertEquals(batchRunConfigKeys.size(), 0);
    // complete criteria key
    String dspCompleteCriteriaKey = EnAwsS3DspConfigs.DSP_COMPLETE_CRITERIA_KEY_AUTO_PREFIX.get();
    super.uploadCustomCompleteCriteriaFile(
        IsaCommonMethods.buildWpReport(REPORT_NAME), super.getTestRunId());
    Set<S3ObjectSummary> dspCompleteCriteriaKeys =
        delphi.aws().s3().listS3Objects(EnAwsS3Buckets.DELPHI_CONFIG.get(), dspCompleteCriteriaKey);
    dspCompleteCriteriaKeys.forEach(delphi.aws().s3()::deleteS3ObjectSummary);
    dspCompleteCriteriaKeys =
        delphi.aws().s3().listS3Objects(EnAwsS3Buckets.DELPHI_CONFIG.get(), dspConfigKey);
    Assert.assertEquals(dspCompleteCriteriaKeys.size(), 0);
    // dsp specific settings
    String dspSpecificSettingsKey = EnAwsS3DspConfigs.DSP_SPECIFIC_SETTINGS_AUTO_PREFIX.get();
    Set<S3ObjectSummary> dspSpecificSettingsKeys =
        delphi.aws().s3().listS3Objects(EnAwsS3Buckets.DELPHI_CONFIG.get(), dspSpecificSettingsKey);
    dspSpecificSettingsKeys.forEach(delphi.aws().s3()::deleteS3ObjectSummary);
    dspSpecificSettingsKeys =
        delphi.aws().s3().listS3Objects(EnAwsS3Buckets.DELPHI_CONFIG.get(), dspConfigKey);
    Assert.assertEquals(dspSpecificSettingsKeys.size(), 0);
    // apps etl config
    String appsEtlConfigKey = EnAwsS3DspConfigs.APPS_ETL_CONFIG_KEY_AUTO_PREFIX.get();
    Set<S3ObjectSummary> appsEtlConfigKeys =
        delphi.aws().s3().listS3Objects(EnAwsS3Buckets.DELPHI_CONFIG.get(), appsEtlConfigKey);
    appsEtlConfigKeys.forEach(delphi.aws().s3()::deleteS3ObjectSummary);
    appsEtlConfigKeys =
        delphi.aws().s3().listS3Objects(EnAwsS3Buckets.DELPHI_CONFIG.get(), dspConfigKey);
    Assert.assertEquals(appsEtlConfigKeys.size(), 0);
  }

  @Test
  public void tc031_addContextFileToArchiveBucket() {
    this.testUploadContextsToAwsS3Bucket(
        envConfig.isAutomationDb()
            ? EnAwsS3Buckets.DELPHI_SME_DATA_ARCHIVE_AUTO.get()
            : EnAwsS3Buckets.DELPHI_SME_DATA_ARCHIVE.get(),
        "1000",
        true);
  }

  @Test
  public void tc032_addContextFileToDecompressedBucket() {
    this.testUploadContextsToAwsS3Bucket(
        envConfig.isAutomationDb()
            ? EnAwsS3Buckets.DELPHI_SME_DATA_DECOMPRESED_AUTO.get()
            : EnAwsS3Buckets.DELPHI_SME_DATA_DECOMPRESED.get(),
        "0001",
        false);
  }

  @Test
  public void tc033_addMockContextsToAutomationBucket() {
    this.testUploadMockContextsToAwsS3Bucket(EnAwsS3Buckets.DELPHI_AUTOTESTS.get(), "1000", true);
    this.testUploadMockContextsToAwsS3Bucket(EnAwsS3Buckets.DELPHI_AUTOTESTS.get(), "0000", false);
  }

  @Test
  public void tc034_addDspConfigKeyToAutomationSubBucket() {
    WpSlzUnitOfWork wpSlzUnitOfWork = getWpSlzUnitOfWork();
    // config key
    String dspConfigKey =
        String.format(EnAwsS3DspConfigs.DSP_CONFIG_KEY_AUTO_PATTERN.get(), super.getTestRunId());
    super.uploadCustomDspConfigFile(wpSlzUnitOfWork, super.getTestRunId());
    Set<S3ObjectSummary> dspConfigKeys =
        delphi.aws().s3().listS3Objects(EnAwsS3Buckets.DELPHI_CONFIG.get(), dspConfigKey);
    Assert.assertEquals(dspConfigKeys.size(), 1);
  }

  private void testUploadContextsToAwsS3Bucket(
      String bucketName, String mockCode, boolean isArchive) {
    WpSlzUnitOfWork wpSlzUnitOfWork = getWpSlzUnitOfWork();
    // delete mock dsp source file
    ensureS3HasNoObjects(bucketName, IsaCommonMethods.buildS3BucketPrefix(wpSlzUnitOfWork));
    // upload dsp source mock file
    super.uploadContext(wpSlzUnitOfWork, mockCode, isArchive, bucketName);
    // upload dsp config for test run to s3
    Set<S3ObjectSummary> s3ObjectSummaries =
        delphi
            .aws()
            .s3()
            .listS3Objects(bucketName, IsaCommonMethods.buildS3BucketPrefix(wpSlzUnitOfWork));
    Assert.assertEquals(s3ObjectSummaries.size(), 1);
  }

  private void testUploadMockContextsToAwsS3Bucket(
      String bucketName, String mockCode, boolean isArchive) {
    WpSlzUnitOfWork wpSlzUnitOfWork = getWpSlzUnitOfWork();
    // delete mock dsp source file
    ensureS3HasNoObjects(bucketName, IsaCommonMethods.buildS3BucketPrefix(wpSlzUnitOfWork));
    // upload dsp source mock file
    super.uploadMockDspContextFile(wpSlzUnitOfWork, mockCode, isArchive);
    // upload dsp config for test run to s3
    Set<S3ObjectSummary> s3ObjectSummaries =
        delphi
            .aws()
            .s3()
            .listS3Objects(bucketName, IsaCommonMethods.buildS3BucketPrefix(wpSlzUnitOfWork));
    Assert.assertEquals(s3ObjectSummaries.size(), 1);
  }
}
