package hdcp2

import (
    "android/soong/android"
    "android/soong/cc"
    "regexp"
    "strconv"
    "fmt"
)

// =============================================================================
// hdcp2 configs
// =============================================================================
func hdcp2ConfigsDefaults(ctx android.LoadHookContext) {
    type props struct {
        Shared_libs []string
        Cflags []string
        Include_dirs []string
    }

    var cflags []string
    var sharedLibs []string
    var include_dirs []string
    var shipping_api_level int

    p := &props{}

    // for QC
    chip_name, _ := ctx.AConfig().GetMkVar("TARGET_CHIP_NAME")
    // for teegris
    use_teegris, _ := ctx.AConfig().GetMkVar("USE_BLOWFISH")
    // for kinibi
    use_kinibi, _ := ctx.AConfig().GetMkVar("USE_MOBICORE")
    soc_name, _ := ctx.AConfig().GetMkVar("TARGET_SOC")
    model_name, _ := ctx.AConfig().GetMkVar("TARGET_PRODUCT")

    sec_ap_chip_vendor, _ := ctx.AConfig().GetMkVar("SEC_AP_CHIP_VENDOR")
    build_variant, _ := ctx.AConfig().GetMkVar("TARGET_BUILD_VARIANT")
    hidl_support, _ := ctx.AConfig().GetMkVar("PRODUCT_TRUSTZONE_SUPPORT_HIDL")
    product_trustzone_enabled, _ := ctx.AConfig().GetMkVar("PRODUCT_TRUSTZONE_ENABLED")
    shipping_api_level_, _ := ctx.AConfig().GetMkVar("PRODUCT_SHIPPING_API_LEVEL")
    shipping_api_level, _ = strconv.Atoi(shipping_api_level_)
    product_trustzone_type, _ := ctx.AConfig().GetMkVar("PRODUCT_TRUSTZONE_TYPE")
    platform_version, _ := ctx.AConfig().GetMkVar("PLATFORM_VERSION")

    if product_trustzone_enabled != "true" {
        fmt.Println("[HDCP] not defined TEE")
    } else {
        if sec_ap_chip_vendor == "qcom" {
	   if chip_name == "SM8350" {
                fmt.Print("[hdcp2] CHIPSET_SM8350 ...\n")
                cflags = append(cflags,
                        "-DCONFIG_SM8350",
                        "-DCONFIG_HDCP_64BIT",
                        "-DUSE_4KMIRRORING",
                        "-DCONFIG_ION_TYPE_MODERN")            
	   } else if chip_name == "SM8250" {
                fmt.Print("[hdcp2] CHIPSET_SM8250 ...\n")
                cflags = append(cflags,
                        "-DCONFIG_SM8250",
                        "-DCONFIG_HDCP_64BIT",
                        "-DUSE_4KMIRRORING",
                        "-DCONFIG_ION_TYPE_MODERN")
	    } else if envIsContains(chip_name, "SM8150") {
                fmt.Print("[hdcp2] CHIPSET_SM8150 ...\n")
                cflags = append(cflags,
                        "-DCONFIG_SM8150",
                        "-DCONFIG_HDCP_64BIT",
                        "-DUSE_4KMIRRORING",
                        "-DCONFIG_ION_TYPE_MODERN")
            } else if chip_name == "SM7250" {
                fmt.Print("[hdcp2] CHIPSET_SM7250 ...\n")
                cflags = append(cflags,
                        "-DCONFIG_SM7250",
                        "-DCONFIG_HDCP_64BIT",
                        "-DCONFIG_ION_TYPE_MODERN")
            } else if chip_name == "SM7225" {
                fmt.Print("[hdcp2] CHIPSET_SM7225 ...\n")
                cflags = append(cflags,
                        "-DCONFIG_SM7225",
                        "-DCONFIG_HDCP_64BIT",
                        "-DCONFIG_ION_TYPE_MODERN")
            } else if chip_name == "SM6150" {
                fmt.Print("[hdcp2] CHIPSET_SM6150 ...\n")
                cflags = append(cflags,
                        "-DCONFIG_SM6150",
                        "-DCONFIG_HDCP_64BIT",
                        "-DCONFIG_ION_TYPE_MODERN")
            } else if chip_name == "SM7150" {
                fmt.Print("[hdcp2] CHIPSET_SM7150 ...\n")
                cflags = append(cflags,
                        "-DCONFIG_SM7150",
                        "-DCONFIG_HDCP_64BIT",
                        "-DCONFIG_ION_TYPE_MODERN")
            } else if chip_name == "SM6115" {
                fmt.Print("[hdcp2] CHIPSET_SM6115 ...\n")
                cflags = append(cflags,
                        "-DCONFIG_SM6115",
                        "-DCONFIG_HDCP_64BIT",
                        "-DCONFIG_ION_TYPE_MODERN")
            } else if chip_name == "SDM845" {
                fmt.Print("[hdcp2] CHIPSET_SDM845 ...\n")
                cflags = append(cflags,
                        "-DCONFIG_SDM845",
                        "-DCONFIG_HDCP_64BIT",
                        "-DUSE_4KMIRRORING")
            } else if chip_name == "SDM710" {
                fmt.Print("[hdcp2] CHIPSET_SDM710 ...\n")
                cflags = append(cflags,
                        "-DCONFIG_SDM710",
                        "-DCONFIG_HDCP_64BIT")
            } else if chip_name == "SDM670" {
                fmt.Print("[hdcp2] CHIPSET_SDM670 ...\n")
                cflags = append(cflags,
                        "-DCONFIG_SDM670",
                        "-DCONFIG_HDCP_64BIT")
            } else if chip_name == "SDM660" {
                fmt.Print("[hdcp2] CHIPSET_SDM660 ...\n")
                cflags = append(cflags,
                        "-DCONFIG_SDM660",
                        "-DCONFIG_HDCP_64BIT")
            } else if chip_name == "SDM450" {
                if product_trustzone_type == "sdm439" {
                    fmt.Print("[hdcp2] CHIPSET_SDM439 ...\n")
                    cflags = append(cflags,
                            "-DCONFIG_SDM439",
                            "-DCONFIG_HDCP_64BIT")
                } else if product_trustzone_type == "sdm429" {
                    fmt.Print("[hdcp2] CHIPSET_SDM429 ...\n")
                    cflags = append(cflags,
                            "-DCONFIG_SDM429",
                            "-DCONFIG_HDCP_64BIT")
                } else {
                    fmt.Print("[hdcp2] CHIPSET_SDM450 ...\n")
                    cflags = append(cflags,
                            "-DCONFIG_SDM450",
                            "-DCONFIG_HDCP_64BIT",
                            "-DUSE_QSEE_WRAP_WITH_SFS")
                }
            } else if chip_name == "SDM429" {
                fmt.Print("[hdcp2] CHIPSET_SDM429 ...\n")
                cflags = append(cflags,
                        "-DCONFIG_SDM429",
                        "-DCONFIG_HDCP_64BIT")
            } else if chip_name == "MSM8998" {
                fmt.Print("[hdcp2] CHIPSET_MSM8998 ...\n")
                cflags = append(cflags,
                        "-DCONFIG_MSM8998",
                        "-DCONFIG_HDCP_64BIT",
                        "-DUSE_4KMIRRORING",
                        "-DUSE_QSEE_WRAP_WITH_SFS")
            } else if chip_name == "MSM8996" {
                fmt.Print("[hdcp2] CHIPSET_MSM8996 ...\n")
                cflags = append(cflags,
                        "-DCONFIG_MSM8996",
                        "-DCONFIG_HDCP_64BIT",
                        "-DUSE_QSEE_WRAP_WITH_SFS")
            } else if chip_name == "MSM8976" {
                fmt.Print("[hdcp2] CHIPSET_MSM8976 ...\n")
                cflags = append(cflags,
                        "-DCONFIG_MSM8976",
                        "-DUSE_QSEE_WRAP_WITH_SFS")
            } else if chip_name == "MSM8976PRO" {
                fmt.Print("[hdcp2] CHIPSET_MSM8976PRO ...\n")
                cflags = append(cflags,
                        "-DCONFIG_MSM8976PRO",
                        "-DCONFIG_HDCP_64BIT",
                        "-DUSE_QSEE_WRAP_WITH_SFS")
            } else if chip_name == "MSM8953" {
                fmt.Print("[hdcp2] CHIPSET_MSM8953 ...\n")
                cflags = append(cflags,
                        "-DCONFIG_MSM8953",
                        "-DCONFIG_HDCP_64BIT",
                        "-DUSE_QSEE_WRAP_WITH_SFS")
            } else if chip_name == "MSM8917" {
                fmt.Print("[hdcp2] CHIPSET_MSM8917 ...\n")
                cflags = append(cflags,
                        "-DCONFIG_MSM8917",
                        "-DUSE_QSEE_WRAP_WITH_SFS")
            } else if chip_name == "MSM8916" {
                fmt.Print("[hdcp2] CHIPSET_MSM8916 ...\n")
                cflags = append(cflags,
                        "-DCONFIG_MSM8916",
                        "-DUSE_QSEE_WRAP_WITH_SFS")
            }

            cflags = append(cflags,
                    "-ULINUX",
                    "-DUSE_QUALCOMM",
                    "-DUSE_TRUSTZONE",
                    "-DCONFIG_USE_VENDOR_PATH")

            if hidl_support != "true" {
                fmt.Print("[hdcp2] This project is not support hidl yet ...\n")
            }
            sharedLibs = append(sharedLibs, 
                    "libQSEEComAPI_system")
        } else if use_teegris == "true" {
            cflags = append(cflags,
                    "-DUSE_TEEGRIS",
                    "-DUSE_EXYNOS",
                    "-DUSE_TRUSTZONE")

            sharedLibs = append(sharedLibs, 
                    "libteecl")
        } else if use_kinibi == "true" {
            fmt.Print("[hdcp2] SOC : " + soc_name + "\n")
            fmt.Print("[hdcp2] MODEL : " + model_name + "\n")
            cflags = append(cflags,
                    "-DUSE_MOBICORE")

            if soc_name == "exynos9810" {
                fmt.Print("[hdcp2] CHIPSET exynos9810 ...\n")
                cflags = append(cflags,
                        "-DUSE_64BIT_ADDR",
                        "-DUSE_4KMIRRORING")
                sharedLibs = append(sharedLibs,
                        "libTeeClient")
                if shipping_api_level >= 29 {
                    include_dirs = append(include_dirs,
                            "hardware/samsung_slsi/exynos9810/mobicore/system/TeeClient/include")
                } else {
                    include_dirs = append(include_dirs,
                            "hardware/samsung_slsi/exynos9810/mobicore/TeeClient/include")
                }
            } else if soc_name == "exynos8895" {
                fmt.Print("[hdcp2] CHIPSET exynos8895 ...\n")
                cflags = append(cflags,
                        "-DUSE_4KMIRRORING")
                sharedLibs = append(sharedLibs,
                        "libTeeClient")
                if shipping_api_level >= 29 {
                    include_dirs = append(include_dirs,
                            "hardware/samsung_slsi/exynos8895/mobicore/system/TeeClient/include")
                } else {
                    include_dirs = append(include_dirs,
                            "hardware/samsung_slsi/exynos8895/mobicore/TeeClient/include")
                }
            } else if soc_name == "exynos8890" {
                fmt.Print("[hdcp2] CHIPSET exynos8890 ...\n")
                if !envIsContains(model_name, "grace") {
                    cflags = append(cflags,
                            "-DUSE_MC310")
                }
                sharedLibs = append(sharedLibs,
                        "libMcClient")
            } else if soc_name == "exynos7420" {
                fmt.Print("[hdcp2] CHIPSET exynos7420 ...\n")
                cflags = append(cflags,
                        "-DUSE_SECMEM_IOC_CHUNK")
                sharedLibs = append(sharedLibs,
                        "libMcClient")
            } else if soc_name == "exynos7884" || soc_name == "exynos7884A" || soc_name == "exynos7885" || soc_name == "exynos7904"{
                fmt.Print("[hdcp2] CHIPSET exynos7885 ...\n")
                cflags = append(cflags,
                        "-DUSE_64BIT_ADDR")
                sharedLibs = append(sharedLibs,
                        "libTeeClient")
                if shipping_api_level >= 29 {
                    include_dirs = append(include_dirs,
                            "hardware/samsung_slsi/exynos7885/mobicore/system/TeeClient/include")
                } else {
                    include_dirs = append(include_dirs,
                            "hardware/samsung_slsi/exynos7885/mobicore/TeeClient/include")
                }
            } else if soc_name == "exynos7880" {
                fmt.Print("[hdcp2] CHIPSET exynos7880 ...\n")
                cflags = append(cflags,
                        "-DUSE_MC310",
                        "-DUSE_SECMEM_IOC_CHUNK")
                sharedLibs = append(sharedLibs,
                        "libMcClient")
            } else if soc_name == "exynos7870" {
                fmt.Print("[hdcp2] CHIPSET exynos7870 ...\n")
                cflags = append(cflags,
                        "-DUSE_MC310",
                        "-DUSE_SECMEM_IOC_CHUNK")
                sharedLibs = append(sharedLibs,
                        "libMcClient")
                include_dirs = append(include_dirs,
                        "hardware/samsung_slsi/exynos7870/mobicore/ClientLib/include")
            } else if soc_name == "exynos7580" {
                fmt.Print("[hdcp2] CHIPSET exynos7580 ...\n")
                cflags = append(cflags,
                        "-DUSE_SECMEM_IOC_CHUNK")
                sharedLibs = append(sharedLibs,
                        "libMcClient")
            } else if soc_name == "MT6768" {
                fmt.Print("[hdcp2] CHIPSET MT6768 ...\n")
                cflags = append(cflags,
                        "-DUSE_64BIT_ADDR")
                sharedLibs = append(sharedLibs,
                        "libTeeClient")
                include_dirs = append(include_dirs,
                        "vendor/mediatek/proprietary/trustzone/trustonic/system_app/mobicore/common/410/TeeClient/include/")
            }
        }
        if sec_ap_chip_vendor == "mediatek" {
            fmt.Print("[hdcp2] CHIPSET mediatek...\n");
            cflags = append(cflags,
                    "-DUSE_MTK")
        }
    }

    if build_variant == "eng" {
        fmt.Print("[hdcp2] Add DEBUG flag\n")
        cflags = append(cflags,
                "-DDEBUG")
    }
    
    if platform_version == "10" {
        fmt.Print("[hdcp2]: Android Q libion...\n")
        include_dirs = append(include_dirs,
            "system/core/libion",
            "system/core/libion/include/ion",
        )
    } else {
        fmt.Print("[hdcp2]: Android R libion...\n")
        include_dirs = append(include_dirs,
            "system/memory/libion",
            "system/memory/libion/include/ion",
            "system/memory/libion/original-kernel-headers/linux",
        )
    }

    cflags = append(cflags,
            "-DLOG_ANDROID",
            "-DUSE_SYSTEM_PARTITION")

    cflags = append(cflags,
            "-Wno-pragma-pack",
            "-Wno-pragma-pack-suspicious-include")

    p.Shared_libs = sharedLibs
    p.Cflags = cflags
    p.Include_dirs = include_dirs

    ctx.AppendProperties(p)
}

// =============================================================================
// libhdcp2 sources
// =============================================================================
func libhdcp2SrcsDefaults(ctx android.LoadHookContext) {
    type props struct {
        Local_include_dirs []string
        Srcs []string
    }

    var include_dirs []string
    var srcs []string
    var nullsrcs []string

    p := &props{}

    use_kinibi, _ := ctx.AConfig().GetMkVar("USE_MOBICORE")
    use_teegris, _ := ctx.AConfig().GetMkVar("USE_BLOWFISH")
    sec_ap_chip_vendor, _ := ctx.AConfig().GetMkVar("SEC_AP_CHIP_VENDOR")
    product_trustzone_enabled, _ := ctx.AConfig().GetMkVar("PRODUCT_TRUSTZONE_ENABLED")

    // Common Includes
    include_dirs = append(include_dirs,
        "libhdcp2/common",
        "libhdcp2/common/include")

    // Common Srcs
    srcs = append(srcs, 
        "libhdcp2/common/hdcp2_transmitter.cpp",
        "libhdcp2/common/hdcp2_receiver.cpp",
        "libhdcp2/common/hdcp2_common.cpp",
        "libhdcp2/common/hdcp2_smartview.cpp",
        "libhdcp2/common/hdcp2_repeater.cpp",
        "libhdcp2/common/hdcp2_wfd.cpp")

    if product_trustzone_enabled != "true" {
        fmt.Println("[HDCP] not defined TEE")
        srcs = append(nullsrcs, 
                "libhdcp2/common/dummy.cpp")
    } else {
        if sec_ap_chip_vendor == "qcom" {
            include_dirs = append(include_dirs,
                    "libhdcp2/qsee/include")
            srcs = append(srcs, 
                    "libhdcp2/qsee/hdcp2_qualcomm.cpp")
        } else if use_teegris == "true" {
            include_dirs = append(include_dirs,
                    "libhdcp2/teegris/include")
            srcs = append(srcs, 
                    "libhdcp2/teegris/hdcp2_global.cpp")
            if sec_ap_chip_vendor == "mediatek" {
                include_dirs = append(include_dirs,
                        "libhdcp2/teegris/include")
            }
        } else if use_kinibi == "true" {
            include_dirs = append(include_dirs,
                    "libhdcp2/kinibi")
            srcs = append(srcs, 
                    "libhdcp2/kinibi/hdcp2_exynos.cpp")
            if sec_ap_chip_vendor == "mediatek" {
                include_dirs = append(include_dirs,
                        "libhdcp2/kinibi/include")
            }
        } else {
            fmt.Println("[HDCP] not defined TEE")
            srcs = nullsrcs
        }
    }

    p.Local_include_dirs = include_dirs
    p.Srcs = srcs

    ctx.AppendProperties(p)
}

// =============================================================================
// libstagefright_hdcp
// =============================================================================
func libstagefrightSrcsDefaults(ctx android.LoadHookContext) {
    type props struct {
        Srcs []string
        Cflags []string
        Local_include_dirs []string
    }

    var srcs []string
    var cflags []string
    var include_dirs []string
    var nullsrcs []string

    p := &props{}

    use_kinibi, _ := ctx.AConfig().GetMkVar("USE_MOBICORE")
    use_teegris, _ := ctx.AConfig().GetMkVar("USE_BLOWFISH")
    sec_ap_chip_vendor, _ := ctx.AConfig().GetMkVar("SEC_AP_CHIP_VENDOR")
    product_trustzone_enabled, _ := ctx.AConfig().GetMkVar("PRODUCT_TRUSTZONE_ENABLED")

    // Common Includes
    include_dirs = append(include_dirs,
        "libhdcp2/common",
        "libhdcp2/common/include",
        "libstagefright_hdcp")

    // Common Srcs
    srcs = append(srcs, 
            "libstagefright_hdcp/HdcpModuleSec.cpp")

    // Shared libraries

    if product_trustzone_enabled != "true" {
        fmt.Println("[HDCP] not defined TEE")
        srcs = nullsrcs
    } else {
        if sec_ap_chip_vendor == "qcom" {
            include_dirs = append(include_dirs,
                    "libhdcp2/qsee/include")
        } else if use_teegris == "true" {
            include_dirs = append(include_dirs,
                    "libhdcp2/teegris/include")
        } else if use_kinibi == "true" {
            include_dirs = append(include_dirs,
                    "libhdcp2/kinibi")
        } else {
            fmt.Println("[HDCP] not defined TEE")
            srcs = nullsrcs
        }
    }

    p.Srcs = srcs
    p.Cflags = cflags
    p.Local_include_dirs = include_dirs
    ctx.AppendProperties(p)
}

func hdcp2ConfigsFactory() android.Module {
    module := cc.DefaultsFactory()
    android.AddLoadHook(module, hdcp2ConfigsDefaults)
    return module
}

func libhdcp2Factory() android.Module {
    module := cc.DefaultsFactory()
    android.AddLoadHook(module, libhdcp2SrcsDefaults)
    return module
}

func libstagefrightFactory() android.Module {
    module := cc.DefaultsFactory()
    android.AddLoadHook(module, libstagefrightSrcsDefaults)
    return module
}

func init() {
    android.RegisterModuleType("hdcp2_configs_defaults", hdcp2ConfigsFactory)
    android.RegisterModuleType("hdcp2_libhdcp2_defaults", libhdcp2Factory)
    android.RegisterModuleType("hdcp2_libstragefright_defaults", libstagefrightFactory)
}

func envIsContains(key string, key2 string) bool {
    contained, _ := regexp.MatchString(key2, key)
    return contained
}
