/* 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::iter::Enumerate;
use std::vec::IntoIter;

use script_bindings::str::DOMString;

use super::Node;
use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use crate::dom::bindings::root::DomRoot;

/// The context during evaluation of an XPath expression.
#[derive(Debug)]
pub(crate) struct EvaluationCtx {
    /// Where we started at
    pub(crate) starting_node: DomRoot<Node>,
    /// The "current" node in the evaluation
    pub(crate) context_node: DomRoot<Node>,
    /// Details needed for evaluating a predicate list
    pub(crate) predicate_ctx: Option<PredicateCtx>,
    /// The nodes we're currently matching against
    pub(crate) predicate_nodes: Option<Vec<DomRoot<Node>>>,
}

#[derive(Clone, Copy, Debug)]
pub(crate) struct PredicateCtx {
    pub(crate) index: usize,
    pub(crate) size: usize,
}

impl EvaluationCtx {
    /// Prepares the context used while evaluating the XPath expression
    pub(crate) fn new(context_node: &Node) -> EvaluationCtx {
        EvaluationCtx {
            starting_node: DomRoot::from_ref(context_node),
            context_node: DomRoot::from_ref(context_node),
            predicate_ctx: None,
            predicate_nodes: None,
        }
    }

    /// Creates a new context using the provided node as the context node
    pub(crate) fn subcontext_for_node(&self, node: &Node) -> EvaluationCtx {
        EvaluationCtx {
            starting_node: self.starting_node.clone(),
            context_node: DomRoot::from_ref(node),
            predicate_ctx: self.predicate_ctx,
            predicate_nodes: self.predicate_nodes.clone(),
        }
    }

    pub(crate) fn update_predicate_nodes(&self, nodes: Vec<&Node>) -> EvaluationCtx {
        EvaluationCtx {
            starting_node: self.starting_node.clone(),
            context_node: self.context_node.clone(),
            predicate_ctx: None,
            predicate_nodes: Some(nodes.into_iter().map(DomRoot::from_ref).collect()),
        }
    }

    pub(crate) fn subcontext_iter_for_nodes(&self) -> EvalNodesetIter<'_> {
        let size = self.predicate_nodes.as_ref().map_or(0, |v| v.len());
        EvalNodesetIter {
            ctx: self,
            nodes_iter: self
                .predicate_nodes
                .as_ref()
                .map_or_else(|| Vec::new().into_iter(), |v| v.clone().into_iter())
                .enumerate(),
            size,
        }
    }

    /// Resolve a namespace prefix using the context node's document
    pub(crate) fn resolve_namespace(&self, prefix: Option<&str>) -> Option<DOMString> {
        self.context_node
            .LookupNamespaceURI(prefix.map(DOMString::from))
    }
}

/// When evaluating predicates, we need to keep track of the current node being evaluated and
/// the index of that node in the nodeset we're operating on.
pub(crate) struct EvalNodesetIter<'a> {
    ctx: &'a EvaluationCtx,
    nodes_iter: Enumerate<IntoIter<DomRoot<Node>>>,
    size: usize,
}

impl Iterator for EvalNodesetIter<'_> {
    type Item = EvaluationCtx;

    fn next(&mut self) -> Option<EvaluationCtx> {
        self.nodes_iter.next().map(|(idx, node)| EvaluationCtx {
            starting_node: self.ctx.starting_node.clone(),
            context_node: node.clone(),
            predicate_nodes: self.ctx.predicate_nodes.clone(),
            predicate_ctx: Some(PredicateCtx {
                index: idx + 1,
                size: self.size,
            }),
        })
    }
}
