import {
  ImportAzureBlobAuthTypeEnum,
  ImportFileTypeEnum,
  ImportGcsAuthTypeEnum,
  ImportOptions,
  ImportOSSAuthTypeEnum,
  ImportS3AuthTypeEnum,
  ImportSource,
  ImportSourceTypeEnum,
  ImportTargetTableInfo
} from 'dbaas/services/api-clients/legacy/serverless/interface'

import type { ImportFromCloudFormData } from './types'

function normalizeSourceUriForImport(data: Pick<ImportFromCloudFormData, 'source_uri' | 'is_single_file'>) {
  if (!data.is_single_file) {
    return data.source_uri
  }

  return data.source_uri.split('/').slice(0, -1).join('/') + '/'
}

export function normalizeImportSource(data: ImportFromCloudFormData): ImportSource | null {
  const targetTableInfos = data.target_table_infos.filter(
    (i) => !!i.target_table?.database && !!i.target_table.table && !!i.custom_file
  )
  const target_table_infos =
    targetTableInfos.length > 0 && !data.use_tidb_dumpling_naming_conventions ? targetTableInfos : undefined
  const sourceUri = normalizeSourceUriForImport(data)

  if (data.storage_provider === ImportSourceTypeEnum.S3) {
    return {
      type: ImportSourceTypeEnum.S3,
      s3: {
        uri: sourceUri,
        ...(data.s3_bucket_access_method === 'manual'
          ? {
              auth_type: ImportS3AuthTypeEnum.ROLE_ARN,
              role_arn: data.aws_role_arn?.trim() ?? ''
            }
          : {
              auth_type: ImportS3AuthTypeEnum.ACCESS_KEY,
              access_key: {
                id: data.aws_access_key_id?.trim() ?? '',
                secret: data.aws_secret_access_key?.trim() ?? ''
              }
            }),
        target_table_infos
      }
    }
  }

  if (data.storage_provider === ImportSourceTypeEnum.GCS) {
    return {
      type: ImportSourceTypeEnum.GCS,
      gcs: {
        uri: sourceUri,
        auth_type: ImportGcsAuthTypeEnum.SERVICE_ACCOUNT_KEY,
        service_account_key: data.gcs_credential?.content,
        target_table_infos: targetTableInfos.length > 0 ? targetTableInfos : undefined
      }
    }
  }

  if (data.storage_provider === ImportSourceTypeEnum.AZURE_BLOB) {
    return {
      type: ImportSourceTypeEnum.AZURE_BLOB,
      azure_blob: {
        uri: sourceUri,
        auth_type: ImportAzureBlobAuthTypeEnum.SAS_TOKEN,
        sas_token: data.azblob_sas_token,
        target_table_infos
      }
    }
  }

  if (data.storage_provider === ImportSourceTypeEnum.OSS) {
    return {
      type: ImportSourceTypeEnum.OSS,
      oss: {
        uri: sourceUri,
        auth_type: ImportOSSAuthTypeEnum.ACCESS_KEY,
        access_key: {
          id: data.aliyun_access_key_id?.trim() ?? '',
          secret: data.aliyun_secret_access_key?.trim() ?? ''
        },
        target_table_infos
      }
    }
  }

  return null
}

export function normalizeImportOptions(data: ImportFromCloudFormData): ImportOptions {
  return {
    file_type: data.data_format === 'UNKNOWN' ? ImportFileTypeEnum.SQL : data.data_format,
    csv_format: data.data_format === ImportFileTypeEnum.CSV ? data.csv_format : undefined
  }
}

const compressed = ['.gzip', '.gz', '.zstd', '.zst', '.snappy']

export function autoDetectDataFormat(targetTableInfos: ImportTargetTableInfo[]): ImportFileTypeEnum | 'UNKNOWN' {
  if (targetTableInfos.length === 0) {
    return 'UNKNOWN'
  }

  const is =
    (type: ImportFileTypeEnum) =>
    (i: ImportTargetTableInfo): boolean => {
      const loweredType = type.toLowerCase()
      const loweredFile = i.custom_file?.toLowerCase() || ''
      return (
        loweredFile.endsWith(`.${loweredType}`) ||
        compressed.some((ext) => loweredFile.endsWith(`.${loweredType}${ext}`))
      )
    }

  if (targetTableInfos.every(is(ImportFileTypeEnum.CSV))) {
    return ImportFileTypeEnum.CSV
  }
  if (targetTableInfos.every(is(ImportFileTypeEnum.SQL))) {
    return ImportFileTypeEnum.SQL
  }
  if (targetTableInfos.every(is(ImportFileTypeEnum.PARQUET))) {
    return ImportFileTypeEnum.PARQUET
  }

  return 'UNKNOWN'
}
