import * as boolbase from "boolbase";
import type { AttributeAction, AttributeSelector } from "css-what";
import type { CompiledQuery, InternalOptions } from "./types.js";

/**
 * All reserved characters in a regex, used for escaping.
 *
 * Taken from XRegExp, (c) 2007-2020 Steven Levithan under the MIT license
 * https://github.com/slevithan/xregexp/blob/95eeebeb8fac8754d54eafe2b4743661ac1cf028/src/xregexp.js#L794
 */
const reChars = /[-[\]{}()*+?.,\\^$|#\s]/g;
function escapeRegex(value: string): string {
    return value.replace(reChars, "\\$&");
}

/**
 * Attributes that are case-insensitive in HTML.
 *
 * @private
 * @see https://html.spec.whatwg.org/multipage/semantics-other.html#case-sensitivity-of-selectors
 */
const caseInsensitiveAttributes = new Set([
    "accept",
    "accept-charset",
    "align",
    "alink",
    "axis",
    "bgcolor",
    "charset",
    "checked",
    "clear",
    "codetype",
    "color",
    "compact",
    "declare",
    "defer",
    "dir",
    "direction",
    "disabled",
    "enctype",
    "face",
    "frame",
    "hreflang",
    "http-equiv",
    "lang",
    "language",
    "link",
    "media",
    "method",
    "multiple",
    "nohref",
    "noresize",
    "noshade",
    "nowrap",
    "readonly",
    "rel",
    "rev",
    "rules",
    "scope",
    "scrolling",
    "selected",
    "shape",
    "target",
    "text",
    "type",
    "valign",
    "valuetype",
    "vlink",
]);

function shouldIgnoreCase<Node, ElementNode extends Node>(
    selector: AttributeSelector,
    options: InternalOptions<Node, ElementNode>,
): boolean {
    return typeof selector.ignoreCase === "boolean"
        ? selector.ignoreCase
        : selector.ignoreCase === "quirks"
          ? !!options.quirksMode
          : !options.xmlMode && caseInsensitiveAttributes.has(selector.name);
}

/**
 * Attribute selectors
 */
export const attributeRules: Record<
    AttributeAction,
    <Node, ElementNode extends Node>(
        next: CompiledQuery<ElementNode>,
        data: AttributeSelector,
        options: InternalOptions<Node, ElementNode>,
    ) => CompiledQuery<ElementNode>
> = {
    equals(next, data, options) {
        const { adapter } = options;
        const { name } = data;
        let { value } = data;

        if (shouldIgnoreCase(data, options)) {
            value = value.toLowerCase();

            return (elem) => {
                const attr = adapter.getAttributeValue(elem, name);
                return (
                    attr != null &&
                    attr.length === value.length &&
                    attr.toLowerCase() === value &&
                    next(elem)
                );
            };
        }

        return (elem) =>
            adapter.getAttributeValue(elem, name) === value && next(elem);
    },
    hyphen(next, data, options) {
        const { adapter } = options;
        const { name } = data;
        let { value } = data;
        const len = value.length;

        if (shouldIgnoreCase(data, options)) {
            value = value.toLowerCase();

            return function hyphenIC(elem) {
                const attr = adapter.getAttributeValue(elem, name);
                return (
                    attr != null &&
                    (attr.length === len || attr.charAt(len) === "-") &&
                    attr.substr(0, len).toLowerCase() === value &&
                    next(elem)
                );
            };
        }

        return function hyphen(elem) {
            const attr = adapter.getAttributeValue(elem, name);
            return (
                attr != null &&
                (attr.length === len || attr.charAt(len) === "-") &&
                attr.substr(0, len) === value &&
                next(elem)
            );
        };
    },
    element(next, data, options) {
        const { adapter } = options;
        const { name, value } = data;
        if (/\s/.test(value)) {
            return boolbase.falseFunc;
        }

        const regex = new RegExp(
            `(?:^|\\s)${escapeRegex(value)}(?:$|\\s)`,
            shouldIgnoreCase(data, options) ? "i" : "",
        );

        return function element(elem) {
            const attr = adapter.getAttributeValue(elem, name);
            return (
                attr != null &&
                attr.length >= value.length &&
                regex.test(attr) &&
                next(elem)
            );
        };
    },
    exists(next, { name }, { adapter }) {
        return (elem) => adapter.hasAttrib(elem, name) && next(elem);
    },
    start(next, data, options) {
        const { adapter } = options;
        const { name } = data;
        let { value } = data;
        const len = value.length;

        if (len === 0) {
            return boolbase.falseFunc;
        }

        if (shouldIgnoreCase(data, options)) {
            value = value.toLowerCase();

            return (elem) => {
                const attr = adapter.getAttributeValue(elem, name);
                return (
                    attr != null &&
                    attr.length >= len &&
                    attr.substr(0, len).toLowerCase() === value &&
                    next(elem)
                );
            };
        }

        return (elem) =>
            !!adapter.getAttributeValue(elem, name)?.startsWith(value) &&
            next(elem);
    },
    end(next, data, options) {
        const { adapter } = options;
        const { name } = data;
        let { value } = data;
        const len = -value.length;

        if (len === 0) {
            return boolbase.falseFunc;
        }

        if (shouldIgnoreCase(data, options)) {
            value = value.toLowerCase();

            return (elem) =>
                adapter
                    .getAttributeValue(elem, name)
                    ?.substr(len)
                    .toLowerCase() === value && next(elem);
        }

        return (elem) =>
            !!adapter.getAttributeValue(elem, name)?.endsWith(value) &&
            next(elem);
    },
    any(next, data, options) {
        const { adapter } = options;
        const { name, value } = data;

        if (value === "") {
            return boolbase.falseFunc;
        }

        if (shouldIgnoreCase(data, options)) {
            const regex = new RegExp(escapeRegex(value), "i");

            return function anyIC(elem) {
                const attr = adapter.getAttributeValue(elem, name);
                return (
                    attr != null &&
                    attr.length >= value.length &&
                    regex.test(attr) &&
                    next(elem)
                );
            };
        }

        return (elem) =>
            !!adapter.getAttributeValue(elem, name)?.includes(value) &&
            next(elem);
    },
    not(next, data, options) {
        const { adapter } = options;
        const { name } = data;
        let { value } = data;

        if (value === "") {
            return (elem) =>
                !!adapter.getAttributeValue(elem, name) && next(elem);
        }
        if (shouldIgnoreCase(data, options)) {
            value = value.toLowerCase();

            return (elem) => {
                const attr = adapter.getAttributeValue(elem, name);
                return (
                    (attr == null ||
                        attr.length !== value.length ||
                        attr.toLowerCase() !== value) &&
                    next(elem)
                );
            };
        }

        return (elem) =>
            adapter.getAttributeValue(elem, name) !== value && next(elem);
    },
};
