/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::fmt;

use dom_struct::dom_struct;
use js::jsapi::CompilationType;
use js::rust::HandleValue;

use crate::dom::bindings::codegen::Bindings::TrustedScriptBinding::TrustedScriptMethods;
use crate::dom::bindings::codegen::UnionTypes::TrustedScriptOrString;
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::reflector::{Reflector, reflect_dom_object};
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::DOMString;
use crate::dom::csp::CspReporting;
use crate::dom::globalscope::GlobalScope;
use crate::dom::trustedtypepolicy::TrustedType;
use crate::dom::trustedtypepolicyfactory::{DEFAULT_SCRIPT_SINK_GROUP, TrustedTypePolicyFactory};
use crate::script_runtime::{CanGc, JSContext};

#[dom_struct]
pub struct TrustedScript {
    reflector_: Reflector,

    data: DOMString,
}

impl TrustedScript {
    fn new_inherited(data: DOMString) -> Self {
        Self {
            reflector_: Reflector::new(),
            data,
        }
    }

    #[cfg_attr(crown, allow(crown::unrooted_must_root))]
    pub(crate) fn new(data: DOMString, global: &GlobalScope, can_gc: CanGc) -> DomRoot<Self> {
        reflect_dom_object(Box::new(Self::new_inherited(data)), global, can_gc)
    }

    pub(crate) fn get_trusted_script_compliant_string(
        global: &GlobalScope,
        value: TrustedScriptOrString,
        sink: &str,
        can_gc: CanGc,
    ) -> Fallible<DOMString> {
        match value {
            TrustedScriptOrString::String(value) => {
                TrustedTypePolicyFactory::get_trusted_type_compliant_string(
                    TrustedType::TrustedScript,
                    global,
                    value,
                    sink,
                    DEFAULT_SCRIPT_SINK_GROUP,
                    can_gc,
                )
            },

            TrustedScriptOrString::TrustedScript(trusted_script) => Ok(trusted_script.data.clone()),
        }
    }

    pub(crate) fn data(&self) -> DOMString {
        self.data.clone()
    }

    /// <https://www.w3.org/TR/CSP/#can-compile-strings>
    #[allow(clippy::too_many_arguments)]
    pub(crate) fn can_compile_string_with_trusted_type(
        cx: JSContext,
        global: &GlobalScope,
        code_string: DOMString,
        compilation_type: CompilationType,
        _parameter_strings: u8, // FIXME in bindings generation
        body_string: DOMString,
        _parameter_args: u8, // FIXME in bindings generation
        body_arg: HandleValue,
        can_gc: CanGc,
    ) -> bool {
        // Step 2.1. Let compilationSink be "Function" if compilationType is "FUNCTION",
        // and "eval" otherwise.
        let compilation_sink = if compilation_type == CompilationType::Function {
            "Function"
        } else {
            "eval"
        };
        // Step 2.2. Let isTrusted be true if bodyArg implements TrustedScript,
        // and false otherwise.
        let is_trusted = match TrustedTypePolicyFactory::is_trusted_script(cx, body_arg) {
            // Step 2.3. If isTrusted is true then:
            Ok(trusted_script) => {
                // Step 2.3.1. If bodyString is not equal to bodyArg’s data, set isTrusted to false.
                body_string == trusted_script.data
            },
            _ => false,
        };
        // Step 2.4. If isTrusted is true, then:
        // Step 2.4.1. Assert: parameterArgs’ [list/size=] is equal to [parameterStrings]' size.
        // Step 2.4.2. For each index of the range 0 to |parameterArgs]' [list/size=]:
        // Step 2.4.2.1. Let arg be parameterArgs[index].
        // Step 2.4.2.2. If arg implements TrustedScript, then:
        // Step 2.4.2.2.1. if parameterStrings[index] is not equal to arg’s data,
        // set isTrusted to false.
        // Step 2.4.2.3. Otherwise, set isTrusted to false.
        // Step 2.5. Let sourceToValidate be a new TrustedScript object created in realm
        // whose data is set to codeString if isTrusted is true, and codeString otherwise.
        let source_string = if is_trusted {
            // We don't need to call the compliant string algorithm, as it would immediately
            // unroll the type as allowed by copying the data. This allows us to skip creating
            // the DOM object.
            code_string
        } else {
            // Step 2.6. Let sourceString be the result of executing the
            // Get Trusted Type compliant string algorithm, with TrustedScript, realm,
            // sourceToValidate, compilationSink, and 'script'.
            match TrustedScript::get_trusted_script_compliant_string(
                global,
                TrustedScriptOrString::String(code_string.clone()),
                compilation_sink,
                can_gc,
            ) {
                // Step 2.7. If the algorithm throws an error, throw an EvalError.
                Err(_) => {
                    return false;
                },
                Ok(source_string) => {
                    // Step 2.8. If sourceString is not equal to codeString, throw an EvalError.
                    if source_string != code_string {
                        return false;
                    }
                    source_string
                },
            }
        };
        global
            .get_csp_list()
            .is_js_evaluation_allowed(global, &source_string)
    }
}

impl fmt::Display for TrustedScript {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(&self.data)
    }
}

impl TrustedScriptMethods<crate::DomTypeHolder> for TrustedScript {
    /// <https://www.w3.org/TR/trusted-types/#trustedscript-stringification-behavior>
    fn Stringifier(&self) -> DOMString {
        self.data.clone()
    }

    /// <https://www.w3.org/TR/trusted-types/#dom-trustedscript-tojson>
    fn ToJSON(&self) -> DOMString {
        self.data.clone()
    }
}
