package io.delphi.qa.auto.awsmfrw.tests.etl.orch;

import com.amazonaws.services.s3.model.S3ObjectSummary;
import com.google.common.collect.Lists;
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.common_baby.exceptions.ReportNotFoundException;
import io.delphi.qa.auto.awsmfrw.common_baby.file_system.EnFsResourcesLocators;
import io.delphi.qa.auto.awsmfrw.models.*;
import io.delphi.qa.auto.awsmfrw.models.aws.lm.WpSlzUnitOfWork;
import io.delphi.qa.auto.awsmfrw.models.etl.orch.DependenciesItem;
import io.delphi.qa.auto.awsmfrw.models.etl.orch.EnAppsEtlUowDependencyTypeItems;
import io.delphi.qa.auto.awsmfrw.models.etl.orch.Ml_AwsAppsEtlUow;
import io.delphi.qa.auto.awsmfrw.suppliers.DelphiDataContainer;
import io.delphi.qa.auto.awsmfrw.tests.slz.BsSlzTest;
import io.qameta.allure.Step;
import org.testng.annotations.Test;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class AwsAppEtlTest extends BsSlzTest {

  static {
    System.setProperty("delphi.slz.db.pg.isAutomation", "false");
  }

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

  @Test
  public void testName() {
    //        String appsEtlReportName = "amazonadsupported-{yyyymmdd}-streams_artist_date_day";
    String appsEtlReportName = "youtubereporting-{yyyymmdd}-streams_isrc_date_day";
    Ml_AwsAppsEtlUow appsEtlUow = findAppsEtlUow(appsEtlReportName);
    // verify dependencies
    List<DependenciesItem> dependencies = appsEtlUow.getDependencies();
    // |--split uow by source
    Set<DependenciesItem> slzUowItems =
        dependencies.stream()
            .filter(o -> o.getType().equals(EnAppsEtlUowDependencyTypeItems.SLZ_UOW.get()))
            .collect(Collectors.toSet());
    Set<DependenciesItem> snowfUowItems =
        dependencies.stream()
            .filter(o -> o.getType().equals(EnAppsEtlUowDependencyTypeItems.SNOWFLAKE.get()))
            .collect(Collectors.toSet());
    Set<DependenciesItem> etlUowItems =
        dependencies.stream()
            .filter(o -> o.getType().equals(EnAppsEtlUowDependencyTypeItems.ETL_UOW.get()))
            .collect(Collectors.toSet());
    // |--ensure slz uow is present
    //    |--|-- gen wp report 1
    MlFw_ReportWrapper r1 =
        new MlFw_ReportWrapper()
            .withDsp(EnDelphiDspItems.YOUTUBEREPORTING)
            .withLicensor(EnDelphiLicensorItems.SME)
            .withReport(EnDelphiReportItems.ASSET_BASIC)
            .withVersion(EnDelphiReportVersionItems.a2);
    WpSlzUnitOfWork uow1 = DelphiDataContainer.genNewMlWpUnitOfWork(r1);
    uow1 =
        uow1.withCompleteCriteriaSet(
            super.getCustomCompleteCriteriaItem(r1, envConfig.whichCompleteCriteria()));
    //    |--|-- gen wp report 2
    MlFw_ReportWrapper r2 =
        new MlFw_ReportWrapper()
            .withDsp(EnDelphiDspItems.YOUTUBEREPORTING)
            .withLicensor(EnDelphiLicensorItems.SME)
            .withReport(EnDelphiReportItems.ASSET_COMBINED)
            .withVersion(EnDelphiReportVersionItems.a2);
    WpSlzUnitOfWork uow2 = DelphiDataContainer.genNewMlWpUnitOfWork(r2);
    uow2 =
        uow2.withCompleteCriteriaSet(
            super.getCustomCompleteCriteriaItem(r2, envConfig.whichCompleteCriteria()));

    ArrayList<WpSlzUnitOfWork> list = Lists.newArrayList(uow1, uow2);
    list.forEach(o -> uploadMockDspContextFile(o, "0000", false));
  }

  private Ml_AwsAppsEtlUow findAppsEtlUow(String appsEtlReportName) {
    List<Ml_AwsAppsEtlUow> hashMapList =
        delphi
            .aws()
            .s3()
            .getS3Object(
                EnAwsS3Buckets.DELPHI_CONFIG.get(),
                EnAwsS3DspConfigs.APPS_ETL_CONFIG_KEY.get(),
                new Ml_AwsAppsEtlUow());
    return hashMapList.stream()
        .filter(o -> o.getUnitOfWork().equals(appsEtlReportName))
        .findFirst()
        .orElseThrow(new ReportNotFoundException());
  }

  @Step("BS::SLZ: upload dsp mock context as archive")
  protected Set<S3ObjectSummary> uploadMockContextFile(
      WpSlzUnitOfWork xWpSlzUnitOfWork, String mockCode, boolean isArchive) {
    File patternFile = filterContextSource(mockCode, delphi
        .fs()
        .listContextSourceFiles(
            xWpSlzUnitOfWork.getDsp().equalsIgnoreCase("apple")
                ? xWpSlzUnitOfWork.getReportName().substring(2)
                : xWpSlzUnitOfWork.getReportName()));
    Set<File> files =
        xWpSlzUnitOfWork.getCompleteCriteriaSet().stream()
            .map(
                completeCriteria ->
                    makeTextFile(
                        patternFile,
                        buildMockContextFileName(
                            xWpSlzUnitOfWork, mockCode, patternFile, completeCriteria)))
            .collect(Collectors.toSet());
    if (isArchive) {
      files =
          files.stream()
              .map(
                  file -> {
                    boolean isGz = gzSet.contains(xWpSlzUnitOfWork.getReportName().toLowerCase());
                    File zipFile =
                        IsaCommonMethods.archiveFile(
                            file,
                            file.getName(),
                            EnFsResourcesLocators.BUILD.get(),
                            String.format(
                                "%s.%s",
                                this.getDspConfigItem(xWpSlzUnitOfWork)
                                    .get(0)
                                    .getArgs()
                                    .getExtension(),
                                isGz ? "gz" : "zip"));
                    return zipFile;
                  })
              .collect(Collectors.toSet());
    }
    return files.stream()
        .map(
            file ->
                delphi
                    .aws()
                    .s3()
                    .addS3File(
                        EnAwsS3Buckets.DELPHI_AUTOTESTS.get(),
                        IsaCommonMethods.buildS3BucketPrefix(xWpSlzUnitOfWork) + file.getName(),
                        file))
        .collect(Collectors.toSet());
  }
}
