/*
 * © 2021 Thoughtworks, Inc.
 */
import {
  getAverage,
  getWattsByAverageOrMedian,
  CloudConstantsByProvider,
  CloudConstantsEmissionsFactors,
  COMPUTE_PROCESSOR_TYPES,
  EstimateUnknownUsageBy,
  US_NERC_REGIONS_EMISSIONS_FACTORS,
} from '@cloud-carbon-footprint/core'

import { AWS_REGIONS } from '../lib/AWSRegions'

export const AWS_CLOUD_CONSTANTS: CloudConstantsByProvider = {
  SSDCOEFFICIENT: 1.2, // watt hours / terabyte hour
  HDDCOEFFICIENT: 0.65, // watt hours / terabyte hour
  MEMORY_AVG: 80.69,
  MEMORY_BY_COMPUTE_PROCESSOR: {
    // gigaBytes / physical chip
    [COMPUTE_PROCESSOR_TYPES.BROADWELL]: 69.65,
    [COMPUTE_PROCESSOR_TYPES.CASCADE_LAKE]: 105.97,
    [COMPUTE_PROCESSOR_TYPES.COFFEE_LAKE]: 19.56,
    [COMPUTE_PROCESSOR_TYPES.AMD_EPYC_1ST_GEN]: 92.44,
    [COMPUTE_PROCESSOR_TYPES.AMD_EPYC_2ND_GEN]: 129.78,
    [COMPUTE_PROCESSOR_TYPES.AMD_EPYC_3RD_GEN]: 137.14,
    [COMPUTE_PROCESSOR_TYPES.AMD_EPYC_4TH_GEN]: 152.2,
    [COMPUTE_PROCESSOR_TYPES.AMD_EPYC_5TH_GEN]: 74.62,
    [COMPUTE_PROCESSOR_TYPES.EMERALD_RAPIDS]: 160,
    [COMPUTE_PROCESSOR_TYPES.GRANITE_RAPIDS]: 221.14,
    [COMPUTE_PROCESSOR_TYPES.AWS_GRAVITON_2]: 129.78,
    [COMPUTE_PROCESSOR_TYPES.AWS_GRAVITON_3]: 129.78,
    [COMPUTE_PROCESSOR_TYPES.AWS_GRAVITON_3E]: 129.78,
    [COMPUTE_PROCESSOR_TYPES.AWS_GRAVITON_4]: 129.78,
    [COMPUTE_PROCESSOR_TYPES.HASWELL]: 31.06,
    [COMPUTE_PROCESSOR_TYPES.ICELAKE]: 136,
    [COMPUTE_PROCESSOR_TYPES.IVY_BRIDGE]: 13.33,
    [COMPUTE_PROCESSOR_TYPES.SANDY_BRIDGE]: 17.07,
    [COMPUTE_PROCESSOR_TYPES.SAPPHIRE_RAPIDS]: 130.8,
    [COMPUTE_PROCESSOR_TYPES.SKYLAKE]: 75.1,
  },
  getMemory: (computeProcessors: string[]): number => {
    const memoryForProcessors: number[] = computeProcessors.map(
      (processor: string) => {
        return AWS_CLOUD_CONSTANTS.MEMORY_BY_COMPUTE_PROCESSOR[processor]
      },
    )
    const averageMemoryForProcessors = getAverage(memoryForProcessors)
    return averageMemoryForProcessors
      ? averageMemoryForProcessors
      : AWS_CLOUD_CONSTANTS.MEMORY_AVG
  },
  MIN_WATTS_AVG: 0.74,
  MIN_WATTS_BY_COMPUTE_PROCESSOR: {
    // CPUs
    [COMPUTE_PROCESSOR_TYPES.APPLE]: 6.8,
    [COMPUTE_PROCESSOR_TYPES.BROADWELL]: 0.71,
    [COMPUTE_PROCESSOR_TYPES.CASCADE_LAKE]: 0.69,
    [COMPUTE_PROCESSOR_TYPES.COFFEE_LAKE]: 1.14,
    [COMPUTE_PROCESSOR_TYPES.AMD_EPYC_1ST_GEN]: 0.85,
    [COMPUTE_PROCESSOR_TYPES.AMD_EPYC_2ND_GEN]: 0.47,
    [COMPUTE_PROCESSOR_TYPES.AMD_EPYC_3RD_GEN]: 0.46,
    [COMPUTE_PROCESSOR_TYPES.AMD_EPYC_4TH_GEN]: 0.74,
    [COMPUTE_PROCESSOR_TYPES.AMD_EPYC_5TH_GEN]: 3.68,
    [COMPUTE_PROCESSOR_TYPES.EMERALD_RAPIDS]: 0.81,
    [COMPUTE_PROCESSOR_TYPES.GRANITE_RAPIDS]: 0.58,
    [COMPUTE_PROCESSOR_TYPES.AWS_GRAVITON_2]: 0.47,
    [COMPUTE_PROCESSOR_TYPES.AWS_GRAVITON_3]: 0.47,
    [COMPUTE_PROCESSOR_TYPES.AWS_GRAVITON_3E]: 0.47,
    [COMPUTE_PROCESSOR_TYPES.AWS_GRAVITON_4]: 0.47,
    [COMPUTE_PROCESSOR_TYPES.HASWELL]: 1.86,
    [COMPUTE_PROCESSOR_TYPES.ICELAKE]: 0.77,
    [COMPUTE_PROCESSOR_TYPES.IVY_BRIDGE]: 1.71,
    [COMPUTE_PROCESSOR_TYPES.SANDY_BRIDGE]: 2.21,
    [COMPUTE_PROCESSOR_TYPES.SAPPHIRE_RAPIDS]: 1.04,
    [COMPUTE_PROCESSOR_TYPES.SKYLAKE]: 0.61,
    // GPUs (GPUWatt Idle = min, GPUWatt 100% = max)
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_B300]: 168,
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_B200]: 120,
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_H200]: 84,
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_H100]: 84,
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_TESLA_A100]: 48,
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_RTX_PRO_6000]: 72,
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_L40S]: 42,
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_L4]: 8.64,
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_A10G]: 18,
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_T4G]: 8.4,
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_T4]: 8.4,
    [COMPUTE_PROCESSOR_TYPES.AMD_RADEON_PRO_V520]: 27,
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_V100_PCIE]: 36,
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_V100_SXM2]: 30,
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_TESLA_K80]: 36,
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_TESLA_M60]: 36,
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_K520]: 27,
  },
  getMinWatts: (computeProcessors: string[]): number => {
    const minWattsForProcessors: number[] = computeProcessors.map(
      (processor: string) => {
        return AWS_CLOUD_CONSTANTS.MIN_WATTS_BY_COMPUTE_PROCESSOR[processor]
      },
    )
    const averageWattsForProcessors = getWattsByAverageOrMedian(
      computeProcessors,
      minWattsForProcessors,
    )
    return averageWattsForProcessors
      ? averageWattsForProcessors
      : AWS_CLOUD_CONSTANTS.MIN_WATTS_AVG
  },
  MAX_WATTS_AVG: 3.5,
  MAX_WATTS_BY_COMPUTE_PROCESSOR: {
    // CPUs
    [COMPUTE_PROCESSOR_TYPES.APPLE]: 39,
    [COMPUTE_PROCESSOR_TYPES.BROADWELL]: 3.69,
    [COMPUTE_PROCESSOR_TYPES.CASCADE_LAKE]: 4.06,
    [COMPUTE_PROCESSOR_TYPES.COFFEE_LAKE]: 5.42,
    [COMPUTE_PROCESSOR_TYPES.AMD_EPYC_1ST_GEN]: 2.6,
    [COMPUTE_PROCESSOR_TYPES.AMD_EPYC_2ND_GEN]: 1.69,
    [COMPUTE_PROCESSOR_TYPES.AMD_EPYC_3RD_GEN]: 1.96,
    [COMPUTE_PROCESSOR_TYPES.AMD_EPYC_4TH_GEN]: 2.28,
    [COMPUTE_PROCESSOR_TYPES.AMD_EPYC_5TH_GEN]: 8.96,
    [COMPUTE_PROCESSOR_TYPES.EMERALD_RAPIDS]: 4.48,
    [COMPUTE_PROCESSOR_TYPES.GRANITE_RAPIDS]: 2.53,
    [COMPUTE_PROCESSOR_TYPES.AWS_GRAVITON_2]: 1.69,
    [COMPUTE_PROCESSOR_TYPES.AWS_GRAVITON_3]: 1.69,
    [COMPUTE_PROCESSOR_TYPES.AWS_GRAVITON_3E]: 1.69,
    [COMPUTE_PROCESSOR_TYPES.AWS_GRAVITON_4]: 1.69,
    [COMPUTE_PROCESSOR_TYPES.HASWELL]: 5.6,
    [COMPUTE_PROCESSOR_TYPES.ICELAKE]: 3.76,
    [COMPUTE_PROCESSOR_TYPES.IVY_BRIDGE]: 5.56,
    [COMPUTE_PROCESSOR_TYPES.SANDY_BRIDGE]: 8.63,
    [COMPUTE_PROCESSOR_TYPES.SAPPHIRE_RAPIDS]: 4.16,
    [COMPUTE_PROCESSOR_TYPES.SKYLAKE]: 4.1,
    // GPUs (GPUWatt Idle = min, GPUWatt 100% = max)
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_B300]: 1428,
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_B200]: 1020,
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_H200]: 714,
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_H100]: 714,
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_TESLA_A100]: 408,
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_RTX_PRO_6000]: 612,
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_L40S]: 357,
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_L4]: 73.44,
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_A10G]: 153,
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_T4G]: 71.4,
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_T4]: 71.4,
    [COMPUTE_PROCESSOR_TYPES.AMD_RADEON_PRO_V520]: 229.5,
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_V100_PCIE]: 306,
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_V100_SXM2]: 255,
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_TESLA_K80]: 306,
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_TESLA_M60]: 306,
    [COMPUTE_PROCESSOR_TYPES.NVIDIA_K520]: 229.5,
  },
  getMaxWatts: (computeProcessors: string[]): number => {
    const maxWattsForProcessors: number[] = computeProcessors.map(
      (processor: string) => {
        return AWS_CLOUD_CONSTANTS.MAX_WATTS_BY_COMPUTE_PROCESSOR[processor]
      },
    )
    const averageWattsForProcessors = getWattsByAverageOrMedian(
      computeProcessors,
      maxWattsForProcessors,
    )
    return averageWattsForProcessors
      ? averageWattsForProcessors
      : AWS_CLOUD_CONSTANTS.MAX_WATTS_AVG
  },
  NETWORKING_COEFFICIENT: 0.001, // kWh / Gb
  MEMORY_COEFFICIENT: 0.000392, // kWh / Gb
  PUE_AVG: 1.135,
  getPUE: (): number => {
    return AWS_CLOUD_CONSTANTS.PUE_AVG
  },
  AVG_CPU_UTILIZATION_2020: 50,
  REPLICATION_FACTORS: {
    S3: 6,
    S3_ONE_ZONE_REDUCED_REDUNDANCY: 2,
    EC2_EBS_VOLUME: 2,
    EC2_EBS_SNAPSHOT: 3,
    EFS: 3,
    EFS_ONE_ZONE: 2,
    RDS_BACKUP: 3,
    RDS_AURORA: 6,
    RDS_MULTI_AZ: 2,
    DOCUMENT_DB_BACKUP: 3,
    DOCUMENT_DB_STORAGE: 2,
    DYNAMO_DB: 2,
    ECR_STORAGE: 3,
    DOCUMENT_ELASTICACHE_BACKUP: 3,
    SIMPLE_DB: 2,
    DEFAULT: 1,
  },
  KILOWATT_HOURS_BY_SERVICE_AND_USAGE_UNIT: {
    total: {},
  },
  ESTIMATE_UNKNOWN_USAGE_BY: EstimateUnknownUsageBy.COST,
  SERVER_EXPECTED_LIFESPAN: 35040, // 4 years in hours
}

export const AWS_EMISSIONS_FACTORS_METRIC_TON_PER_KWH: CloudConstantsEmissionsFactors =
  {
    [AWS_REGIONS.US_EAST_1]: US_NERC_REGIONS_EMISSIONS_FACTORS.SERC,
    [AWS_REGIONS.US_EAST_2]: US_NERC_REGIONS_EMISSIONS_FACTORS.RFC,
    [AWS_REGIONS.US_WEST_1]: US_NERC_REGIONS_EMISSIONS_FACTORS.WECC,
    [AWS_REGIONS.US_WEST_2]: US_NERC_REGIONS_EMISSIONS_FACTORS.WECC,
    [AWS_REGIONS.US_GOV_EAST_1]: US_NERC_REGIONS_EMISSIONS_FACTORS.SERC,
    [AWS_REGIONS.US_GOV_WEST_1]: US_NERC_REGIONS_EMISSIONS_FACTORS.WECC,
    [AWS_REGIONS.AF_SOUTH_1]: 0.00075744,
    [AWS_REGIONS.AP_EAST_1]: 0.00067348,
    [AWS_REGIONS.AP_EAST_2]: 0.00064142,
    [AWS_REGIONS.AP_SOUTH_1]: 0.00095182,
    [AWS_REGIONS.AP_SOUTH_2]: 0.00095182,
    [AWS_REGIONS.AP_NORTHEAST_1]: 0.00043984,
    [AWS_REGIONS.AP_NORTHEAST_2]: 0.00047739,
    [AWS_REGIONS.AP_NORTHEAST_3]: 0.00043984,
    [AWS_REGIONS.AP_SOUTHEAST_1]: 0.00049453,
    [AWS_REGIONS.AP_SOUTHEAST_2]: 0.00058023,
    [AWS_REGIONS.AP_SOUTHEAST_3]: 0.00071767,
    [AWS_REGIONS.AP_SOUTHEAST_4]: 0.00058023,
    [AWS_REGIONS.AP_SOUTHEAST_5]: 0.00062051,
    [AWS_REGIONS.AP_SOUTHEAST_6]: 0.00007939,
    [AWS_REGIONS.AP_SOUTHEAST_7]: 0.00050824,
    [AWS_REGIONS.CA_CENTRAL_1]: 0.00011541,
    [AWS_REGIONS.CA_WEST_1]: 0.00011541,
    [AWS_REGIONS.CN_NORTH_1]: 0.0005374,
    [AWS_REGIONS.CN_NORTHWEST_1]: 0.0005374,
    [AWS_REGIONS.EU_CENTRAL_1]: 0.000368,
    [AWS_REGIONS.EU_CENTRAL_2]: 0.000368,
    [AWS_REGIONS.EU_WEST_1]: 0.000305,
    [AWS_REGIONS.EU_WEST_2]: 0.000305,
    [AWS_REGIONS.EU_WEST_3]: 0.000074,
    [AWS_REGIONS.EU_SOUTH_1]: 0.000297,
    [AWS_REGIONS.EU_SOUTH_2]: 0.000178,
    [AWS_REGIONS.EU_NORTH_1]: 0.000008,
    [AWS_REGIONS.IL_CENTRAL_1]: 0.00053982,
    [AWS_REGIONS.ME_SOUTH_1]: 0.00050549,
    [AWS_REGIONS.ME_CENTRAL_1]: 0.0003652,
    [AWS_REGIONS.MX_CENTRAL_1]: 0.00041896,
    [AWS_REGIONS.SA_EAST_1]: 0.00006398,
    [AWS_REGIONS.UNKNOWN]: 0.0004215330139, // Average of the above regions
  }
