// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2019-Present Datadog, Inc.

use serde::{Deserialize, Deserializer, Serialize, Serializer};

#[non_exhaustive]
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum VulnerabilityType {
    ADMIN_CONSOLE_ACTIVE,
    CODE_INJECTION,
    COMMAND_INJECTION,
    COMPONENT_WITH_KNOWN_VULNERABILITY,
    DANGEROUS_WORKFLOWS,
    DEFAULT_APP_DEPLOYED,
    DEFAULT_HTML_ESCAPE_INVALID,
    DIRECTORY_LISTING_LEAK,
    EMAIL_HTML_INJECTION,
    END_OF_LIFE,
    HARDCODED_PASSWORD,
    HARDCODED_SECRET,
    HEADER_INJECTION,
    HSTS_HEADER_MISSING,
    INSECURE_AUTH_PROTOCOL,
    INSECURE_COOKIE,
    INSECURE_JSP_LAYOUT,
    LDAP_INJECTION,
    MALICIOUS_PACKAGE,
    MANDATORY_REMEDIATION,
    NO_HTTP_ONLY_COOKIE,
    NO_SAME_SITE_COOKIE,
    NO_SQL_MONGO_DB_INJECTION,
    PATH_TRAVERSAL,
    REFLECTION_INJECTION,
    RISKY_LICENSE,
    SESSION_REWRITING,
    SESSION_TIMEOUT,
    SQL_INJECTION,
    SSRF,
    STACK_TRACE_LEAK,
    TRUST_BOUNDARY_VIOLATION,
    UNMAINTAINED,
    UNTRUSTED_DESERIALIZATION,
    UNVALIDATED_REDIRECT,
    VERB_TAMPERING,
    WEAK_CIPHER,
    WEAK_HASH,
    WEAK_RANDOMNESS,
    X_CONTENT_TYPE_HEADER_MISSING,
    X_PATH_INJECTION,
    XSS,
    UnparsedObject(crate::datadog::UnparsedObject),
}

impl ToString for VulnerabilityType {
    fn to_string(&self) -> String {
        match self {
            Self::ADMIN_CONSOLE_ACTIVE => String::from("AdminConsoleActive"),
            Self::CODE_INJECTION => String::from("CodeInjection"),
            Self::COMMAND_INJECTION => String::from("CommandInjection"),
            Self::COMPONENT_WITH_KNOWN_VULNERABILITY => {
                String::from("ComponentWithKnownVulnerability")
            }
            Self::DANGEROUS_WORKFLOWS => String::from("DangerousWorkflows"),
            Self::DEFAULT_APP_DEPLOYED => String::from("DefaultAppDeployed"),
            Self::DEFAULT_HTML_ESCAPE_INVALID => String::from("DefaultHtmlEscapeInvalid"),
            Self::DIRECTORY_LISTING_LEAK => String::from("DirectoryListingLeak"),
            Self::EMAIL_HTML_INJECTION => String::from("EmailHtmlInjection"),
            Self::END_OF_LIFE => String::from("EndOfLife"),
            Self::HARDCODED_PASSWORD => String::from("HardcodedPassword"),
            Self::HARDCODED_SECRET => String::from("HardcodedSecret"),
            Self::HEADER_INJECTION => String::from("HeaderInjection"),
            Self::HSTS_HEADER_MISSING => String::from("HstsHeaderMissing"),
            Self::INSECURE_AUTH_PROTOCOL => String::from("InsecureAuthProtocol"),
            Self::INSECURE_COOKIE => String::from("InsecureCookie"),
            Self::INSECURE_JSP_LAYOUT => String::from("InsecureJspLayout"),
            Self::LDAP_INJECTION => String::from("LdapInjection"),
            Self::MALICIOUS_PACKAGE => String::from("MaliciousPackage"),
            Self::MANDATORY_REMEDIATION => String::from("MandatoryRemediation"),
            Self::NO_HTTP_ONLY_COOKIE => String::from("NoHttpOnlyCookie"),
            Self::NO_SAME_SITE_COOKIE => String::from("NoSameSiteCookie"),
            Self::NO_SQL_MONGO_DB_INJECTION => String::from("NoSqlMongoDbInjection"),
            Self::PATH_TRAVERSAL => String::from("PathTraversal"),
            Self::REFLECTION_INJECTION => String::from("ReflectionInjection"),
            Self::RISKY_LICENSE => String::from("RiskyLicense"),
            Self::SESSION_REWRITING => String::from("SessionRewriting"),
            Self::SESSION_TIMEOUT => String::from("SessionTimeout"),
            Self::SQL_INJECTION => String::from("SqlInjection"),
            Self::SSRF => String::from("Ssrf"),
            Self::STACK_TRACE_LEAK => String::from("StackTraceLeak"),
            Self::TRUST_BOUNDARY_VIOLATION => String::from("TrustBoundaryViolation"),
            Self::UNMAINTAINED => String::from("Unmaintained"),
            Self::UNTRUSTED_DESERIALIZATION => String::from("UntrustedDeserialization"),
            Self::UNVALIDATED_REDIRECT => String::from("UnvalidatedRedirect"),
            Self::VERB_TAMPERING => String::from("VerbTampering"),
            Self::WEAK_CIPHER => String::from("WeakCipher"),
            Self::WEAK_HASH => String::from("WeakHash"),
            Self::WEAK_RANDOMNESS => String::from("WeakRandomness"),
            Self::X_CONTENT_TYPE_HEADER_MISSING => String::from("XContentTypeHeaderMissing"),
            Self::X_PATH_INJECTION => String::from("XPathInjection"),
            Self::XSS => String::from("Xss"),
            Self::UnparsedObject(v) => v.value.to_string(),
        }
    }
}

impl Serialize for VulnerabilityType {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        match self {
            Self::UnparsedObject(v) => v.serialize(serializer),
            _ => serializer.serialize_str(self.to_string().as_str()),
        }
    }
}

impl<'de> Deserialize<'de> for VulnerabilityType {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        let s: String = String::deserialize(deserializer)?;
        Ok(match s.as_str() {
            "AdminConsoleActive" => Self::ADMIN_CONSOLE_ACTIVE,
            "CodeInjection" => Self::CODE_INJECTION,
            "CommandInjection" => Self::COMMAND_INJECTION,
            "ComponentWithKnownVulnerability" => Self::COMPONENT_WITH_KNOWN_VULNERABILITY,
            "DangerousWorkflows" => Self::DANGEROUS_WORKFLOWS,
            "DefaultAppDeployed" => Self::DEFAULT_APP_DEPLOYED,
            "DefaultHtmlEscapeInvalid" => Self::DEFAULT_HTML_ESCAPE_INVALID,
            "DirectoryListingLeak" => Self::DIRECTORY_LISTING_LEAK,
            "EmailHtmlInjection" => Self::EMAIL_HTML_INJECTION,
            "EndOfLife" => Self::END_OF_LIFE,
            "HardcodedPassword" => Self::HARDCODED_PASSWORD,
            "HardcodedSecret" => Self::HARDCODED_SECRET,
            "HeaderInjection" => Self::HEADER_INJECTION,
            "HstsHeaderMissing" => Self::HSTS_HEADER_MISSING,
            "InsecureAuthProtocol" => Self::INSECURE_AUTH_PROTOCOL,
            "InsecureCookie" => Self::INSECURE_COOKIE,
            "InsecureJspLayout" => Self::INSECURE_JSP_LAYOUT,
            "LdapInjection" => Self::LDAP_INJECTION,
            "MaliciousPackage" => Self::MALICIOUS_PACKAGE,
            "MandatoryRemediation" => Self::MANDATORY_REMEDIATION,
            "NoHttpOnlyCookie" => Self::NO_HTTP_ONLY_COOKIE,
            "NoSameSiteCookie" => Self::NO_SAME_SITE_COOKIE,
            "NoSqlMongoDbInjection" => Self::NO_SQL_MONGO_DB_INJECTION,
            "PathTraversal" => Self::PATH_TRAVERSAL,
            "ReflectionInjection" => Self::REFLECTION_INJECTION,
            "RiskyLicense" => Self::RISKY_LICENSE,
            "SessionRewriting" => Self::SESSION_REWRITING,
            "SessionTimeout" => Self::SESSION_TIMEOUT,
            "SqlInjection" => Self::SQL_INJECTION,
            "Ssrf" => Self::SSRF,
            "StackTraceLeak" => Self::STACK_TRACE_LEAK,
            "TrustBoundaryViolation" => Self::TRUST_BOUNDARY_VIOLATION,
            "Unmaintained" => Self::UNMAINTAINED,
            "UntrustedDeserialization" => Self::UNTRUSTED_DESERIALIZATION,
            "UnvalidatedRedirect" => Self::UNVALIDATED_REDIRECT,
            "VerbTampering" => Self::VERB_TAMPERING,
            "WeakCipher" => Self::WEAK_CIPHER,
            "WeakHash" => Self::WEAK_HASH,
            "WeakRandomness" => Self::WEAK_RANDOMNESS,
            "XContentTypeHeaderMissing" => Self::X_CONTENT_TYPE_HEADER_MISSING,
            "XPathInjection" => Self::X_PATH_INJECTION,
            "Xss" => Self::XSS,
            _ => Self::UnparsedObject(crate::datadog::UnparsedObject {
                value: serde_json::Value::String(s.into()),
            }),
        })
    }
}
