// Type definitions for postcss-selector-parser 2.2.3
// Definitions by: Chris Eppstein <chris@eppsteins.net>

/*~ Note that ES6 modules cannot directly export callable functions.
 *~ This file should be imported using the CommonJS-style:
 *~   import x = require('someLibrary');
 *~
 *~ Refer to the documentation to understand common
 *~ workarounds for this limitation of ES6 modules.
 */

/*~ This declaration specifies that the function
 *~ is the exported object from the file
 */
export = parser;

// A type that's T but not U.
type Diff<T, U> = T extends U ? never : T;

// TODO: Conditional types in TS 1.8 will really clean this up.
declare function parser(): parser.Processor<never>;
declare function parser<Transform>(processor: parser.AsyncProcessor<Transform>): parser.Processor<Transform, never>;
declare function parser(processor: parser.AsyncProcessor<void>): parser.Processor<never, never>;
declare function parser<Transform>(processor: parser.SyncProcessor<Transform>): parser.Processor<Transform>;
declare function parser(processor: parser.SyncProcessor<void>): parser.Processor<never>;
declare function parser<Transform>(processor?: parser.SyncProcessor<Transform> | parser.AsyncProcessor<Transform>): parser.Processor<Transform>;

/*~ If you want to expose types from your module as well, you can
 *~ place them in this block. Often you will want to describe the
 *~ shape of the return type of the function; that type should
 *~ be declared in here, as this example shows.
 */
declare namespace parser {
    /* copied from postcss -- so we don't need to add a dependency */
    type ErrorOptions = {
        plugin?: string;
        word?: string;
        index?: number
    };
    /* the bits we use of postcss.Rule, copied from postcss -- so we don't need to add a dependency */
    type PostCSSRuleNode = {
        selector: string
        /**
         * @returns postcss.CssSyntaxError but it's a complex object, caller
         *   should cast to it if they have a dependency on postcss.
         */
        error(message: string, options?: ErrorOptions): Error;
    };
    /** Accepts a string  */
    type Selectors = string | PostCSSRuleNode
    type ProcessorFn<ReturnType = void> = (root: parser.Root) => ReturnType;
    type SyncProcessor<Transform = void> = ProcessorFn<Transform>;
    type AsyncProcessor<Transform = void> = ProcessorFn<PromiseLike<Transform>>;

    const TAG: "tag";
    const STRING: "string";
    const SELECTOR: "selector";
    const ROOT: "root";
    const PSEUDO: "pseudo";
    const NESTING: "nesting";
    const ID: "id";
    const COMMENT: "comment";
    const COMBINATOR: "combinator";
    const CLASS: "class";
    const ATTRIBUTE: "attribute";
    const UNIVERSAL: "universal";

    interface NodeTypes {
        tag: Tag,
        string: String,
        selector: Selector,
        root: Root,
        pseudo: Pseudo,
        nesting: Nesting,
        id: Identifier,
        comment: Comment,
        combinator: Combinator,
        class: ClassName,
        attribute: Attribute,
        universal: Universal
    }

    type Node = NodeTypes[keyof NodeTypes];

    function isNode(node: any): node is Node;

    interface Options {
        /**
         * Preserve whitespace when true. Default: false;
         */
        lossless: boolean;
        /**
         * When true and a postcss.Rule is passed, set the result of
         * processing back onto the rule when done. Default: false.
         */
        updateSelector: boolean;
    }
    class Processor<
        TransformType = never,
        SyncSelectorsType extends Selectors | never = Selectors
    > {
        res: Root;
        readonly result: String;
        ast(selectors: Selectors, options?: Partial<Options>): Promise<Root>;
        astSync(selectors: SyncSelectorsType, options?: Partial<Options>): Root;
        transform(selectors: Selectors, options?: Partial<Options>): Promise<TransformType>;
        transformSync(selectors: SyncSelectorsType, options?: Partial<Options>): TransformType;
        process(selectors: Selectors, options?: Partial<Options>): Promise<string>;
        processSync(selectors: SyncSelectorsType, options?: Partial<Options>): string;
    }
    interface ParserOptions {
        css: string;
        error: (message: string, options: ErrorOptions) => Error;
        options: Options;
    }
    class Parser {
        input: ParserOptions;
        lossy: boolean;
        position: number;
        root: Root;
        selectors: string;
        current: Selector;
        constructor(input: ParserOptions);
        /**
         * Raises an error, if the processor is invoked on
         * a postcss Rule node, a better error message is raised.
         */
        error(message: string, options?: ErrorOptions): void;
    }
    interface NodeSource {
        start?: {
            line: number,
            column: number
        },
        end?: {
            line: number,
            column: number
        }
    }
    interface SpaceAround {
      before: string;
      after: string;
    }
    interface Spaces extends SpaceAround {
      [spaceType: string]: string | Partial<SpaceAround> | undefined;
    }
    interface NodeOptions<Value = string> {
        value: Value;
        spaces?: Partial<Spaces>;
        source?: NodeSource;
        sourceIndex?: number;
    }
    interface Base<
        Value extends string | undefined = string,
        ParentType extends Container | undefined = Container | undefined
    > {
        type: keyof NodeTypes;
        parent: ParentType;
        value: Value;
        spaces: Spaces;
        source?: NodeSource;
        sourceIndex: number;
        rawSpaceBefore: string;
        rawSpaceAfter: string;
        remove(): Node;
        replaceWith(...nodes: Node[]): Node;
        next(): Node;
        prev(): Node;
        clone(opts: {[override: string]:any}): Node;
        /**
         * Return whether this node includes the character at the position of the given line and column.
         * Returns undefined if the nodes lack sufficient source metadata to determine the position.
         * @param line 1-index based line number relative to the start of the selector.
         * @param column 1-index based column number relative to the start of the selector.
         */
        isAtPosition(line: number, column: number): boolean | undefined;
        /**
         * Some non-standard syntax doesn't follow normal escaping rules for css,
         * this allows the escaped value to be specified directly, allowing illegal characters to be
         * directly inserted into css output.
         * @param name the property to set
         * @param value the unescaped value of the property
         * @param valueEscaped optional. the escaped value of the property.
         */
        setPropertyAndEscape(name: string, value: any, valueEscaped: string): void;
        /**
         * When you want a value to passed through to CSS directly. This method
         * deletes the corresponding raw value causing the stringifier to fallback
         * to the unescaped value.
         * @param name the property to set.
         * @param value The value that is both escaped and unescaped.
         */
        setPropertyWithoutEscape(name: string, value: any): void;
        /**
         * Some non-standard syntax doesn't follow normal escaping rules for css.
         * This allows non standard syntax to be appended to an existing property
         * by specifying the escaped value. By specifying the escaped value,
         * illegal characters are allowed to be directly inserted into css output.
         * @param {string} name the property to set
         * @param {any} value the unescaped value of the property
         * @param {string} valueEscaped optional. the escaped value of the property.
         */
        appendToPropertyAndEscape(name: string, value: any, valueEscaped: string): void;
        toString(): string;
    }
    interface ContainerOptions extends NodeOptions {
        nodes?: Array<Node>;
    }
    interface Container<
        Value extends string | undefined = string,
        Child extends Node = Node
    > extends Base<Value> {
        nodes: Array<Child>;
        append(selector: Selector): this;
        prepend(selector: Selector): this;
        at(index: number): Child;
        /**
         * Return the most specific node at the line and column number given.
         * The source location is based on the original parsed location, locations aren't
         * updated as selector nodes are mutated.
         *
         * Note that this location is relative to the location of the first character
         * of the selector, and not the location of the selector in the overall document
         * when used in conjunction with postcss.
         *
         * If not found, returns undefined.
         * @param line The line number of the node to find. (1-based index)
         * @param col  The column number of the node to find. (1-based index)
         */
        atPosition(line: number, column: number): Child;
        index(child: Child): number;
        readonly first: Child;
        readonly last: Child;
        readonly length: number;
        removeChild(child: Child): this;
        removeAll(): Container;
        empty(): Container;
        insertAfter(oldNode: Child, newNode: Child): this;
        insertBefore(oldNode: Child, newNode: Child): this;
        each(callback: (node: Child) => boolean | void): boolean | undefined;
        walk(
            callback: (node: Node) => boolean | void
        ): boolean | undefined;
        walkAttributes(
            callback: (node: Attribute) => boolean | void
        ): boolean | undefined;
        walkClasses(
            callback: (node: ClassName) => boolean | void
        ): boolean | undefined;
        walkCombinators(
            callback: (node: Combinator) => boolean | void
        ): boolean | undefined;
        walkComments(
            callback: (node: Comment) => boolean | void
        ): boolean | undefined;
        walkIds(
            callback: (node: Identifier) => boolean | void
        ): boolean | undefined;
        walkNesting(
            callback: (node: Nesting) => boolean | void
        ): boolean | undefined;
        walkPseudos(
            callback: (node: Pseudo) => boolean | void
        ): boolean | undefined;
        walkTags(callback: (node: Tag) => boolean | void): boolean | undefined;
        split(callback: (node: Child) => boolean): [Child[], Child[]];
        map<T>(callback: (node: Child) => T): T[];
        reduce(
            callback: (
                previousValue: Child,
                currentValue: Child,
                currentIndex: number,
                array: readonly Child[]
            ) => Child
        ): Child;
        reduce(
            callback: (
                previousValue: Child,
                currentValue: Child,
                currentIndex: number,
                array: readonly Child[]
            ) => Child,
            initialValue: Child
        ): Child;
        reduce<T>(
            callback: (
                previousValue: T,
                currentValue: Child,
                currentIndex: number,
                array: readonly Child[]
            ) => T,
            initialValue: T
        ): T;
        every(callback: (node: Child) => boolean): boolean;
        some(callback: (node: Child) => boolean): boolean;
        filter(callback: (node: Child) => boolean): Child[];
        sort(callback: (nodeA: Child, nodeB: Child) => number): Child[];
        toString(): string;
    }
    function isContainer(node: any): node is Root | Selector | Pseudo;

    interface NamespaceOptions<Value extends string | undefined = string> extends NodeOptions<Value> {
        namespace?: string | true;
    }
    interface Namespace<Value extends string | undefined = string> extends Base<Value> {
        /** alias for namespace */
        ns: string | true;
        /**
         *  namespace prefix.
         */
        namespace: string | true;
        /**
         * If a namespace exists, prefix the value provided with it, separated by |.
         */
        qualifiedName(value: string): string;
        /**
         * A string representing the namespace suitable for output.
         */
        readonly namespaceString: string;
    }
    function isNamespace(node: any): node is Attribute | Tag;

    interface Root extends Container<undefined, Selector> {
        type: "root";
        /**
         * Raises an error, if the processor is invoked on
         * a postcss Rule node, a better error message is raised.
         */
        error(message: string, options?: ErrorOptions): Error;
        nodeAt(line: number, column: number): Node
    }
    function root(opts: ContainerOptions): Root;
    function isRoot(node: any): node is Root;

    interface _Selector<S> extends Container<string, Diff<Node, S>> {
        type: "selector";
    }
    type Selector = _Selector<Selector>;
    function selector(opts: ContainerOptions): Selector;
    function isSelector(node: any): node is Selector;

    interface Combinator extends Base {
        type: "combinator"
    }
    function combinator(opts: NodeOptions): Combinator;
    function isCombinator(node: any): node is Combinator;

    interface ClassName extends Base {
        type: "class";
    }
    function className(opts: NamespaceOptions): ClassName;
    function isClassName(node: any): node is ClassName;

    type AttributeOperator = "=" | "~=" | "|=" | "^=" | "$=" | "*=";
    type QuoteMark = '"' | "'" | null;
    interface PreferredQuoteMarkOptions {
        quoteMark?: QuoteMark;
        preferCurrentQuoteMark?: boolean;
    }
    interface SmartQuoteMarkOptions extends PreferredQuoteMarkOptions {
        smart?: boolean;
    }
    interface AttributeOptions extends NamespaceOptions<string | undefined> {
        attribute: string;
        operator?: AttributeOperator;
        insensitive?: boolean;
        quoteMark?: QuoteMark;
        /** @deprecated Use quoteMark instead. */
        quoted?: boolean;
        spaces?: {
            before?: string;
            after?: string;
            attribute?: Partial<SpaceAround>;
            operator?: Partial<SpaceAround>;
            value?: Partial<SpaceAround>;
            insensitive?: Partial<SpaceAround>;
        }
        raws: {
            unquoted?: string;
            attribute?: string;
            operator?: string;
            value?: string;
            insensitive?: string;
            spaces?: {
                attribute?: Partial<Spaces>;
                operator?: Partial<Spaces>;
                value?: Partial<Spaces>;
                insensitive?: Partial<Spaces>;
            }
        };
    }
    interface Attribute extends Namespace<string | undefined> {
        type: "attribute";
        attribute: string;
        operator?: AttributeOperator;
        insensitive?: boolean;
        quoteMark: QuoteMark;
        quoted?: boolean;
        spaces: {
            before: string;
            after: string;
            attribute?: Partial<Spaces>;
            operator?: Partial<Spaces>;
            value?: Partial<Spaces>;
            insensitive?: Partial<Spaces>;
        }
        raws: {
            /** @deprecated The attribute value is unquoted, use that instead.. */
            unquoted?: string;
            attribute?: string;
            operator?: string;
            /** The value of the attribute with quotes and escapes. */
            value?: string;
            insensitive?: string;
            spaces?: {
                attribute?: Partial<Spaces>;
                operator?: Partial<Spaces>;
                value?: Partial<Spaces>;
                insensitive?: Partial<Spaces>;
            }
        };
        /**
         * The attribute name after having been qualified with a namespace.
         */
        readonly qualifiedAttribute: string;

        /**
         * The case insensitivity flag or an empty string depending on whether this
         * attribute is case insensitive.
         */
        readonly insensitiveFlag : 'i' | '';

        /**
         * Returns the attribute's value quoted such that it would be legal to use
         * in the value of a css file. The original value's quotation setting
         * used for stringification is left unchanged. See `setValue(value, options)`
         * if you want to control the quote settings of a new value for the attribute or
         * `set quoteMark(mark)` if you want to change the quote settings of the current
         * value.
         *
         * You can also change the quotation used for the current value by setting quoteMark.
         **/
        getQuotedValue(options?: SmartQuoteMarkOptions): string;

        /**
         * Set the unescaped value with the specified quotation options. The value
         * provided must not include any wrapping quote marks -- those quotes will
         * be interpreted as part of the value and escaped accordingly.
         * @param value
         */
        setValue(value: string, options?: SmartQuoteMarkOptions): void;

        /**
         * Intelligently select a quoteMark value based on the value's contents. If
         * the value is a legal CSS ident, it will not be quoted. Otherwise a quote
         * mark will be picked that minimizes the number of escapes.
         *
         * If there's no clear winner, the quote mark from these options is used,
         * then the source quote mark (this is inverted if `preferCurrentQuoteMark` is
         * true). If the quoteMark is unspecified, a double quote is used.
         **/
        smartQuoteMark(options: PreferredQuoteMarkOptions): QuoteMark;

        /**
         * Selects the preferred quote mark based on the options and the current quote mark value.
         * If you want the quote mark to depend on the attribute value, call `smartQuoteMark(opts)`
         * instead.
         */
        preferredQuoteMark(options: PreferredQuoteMarkOptions): QuoteMark

        /**
         * returns the offset of the attribute part specified relative to the
         * start of the node of the output string.
         *
         * * "ns" - alias for "namespace"
         * * "namespace" - the namespace if it exists.
         * * "attribute" - the attribute name
         * * "attributeNS" - the start of the attribute or its namespace
         * * "operator" - the match operator of the attribute
         * * "value" - The value (string or identifier)
         * * "insensitive" - the case insensitivity flag;
         * @param part One of the possible values inside an attribute.
         * @returns -1 if the name is invalid or the value doesn't exist in this attribute.
         */
        offsetOf(part: "ns" | "namespace" | "attribute" | "attributeNS" | "operator" | "value" | "insensitive"): number;
    }
    function attribute(opts: AttributeOptions): Attribute;
    function isAttribute(node: any): node is Attribute;

    interface Pseudo extends Container<string, Selector> {
        type: "pseudo";
    }
    function pseudo(opts: ContainerOptions): Pseudo;
    /**
     * Checks wether the node is the Psuedo subtype of node.
     */
    function isPseudo(node: any): node is Pseudo;

    /**
     * Checks wether the node is, specifically, a pseudo element instead of
     * pseudo class.
     */
    function isPseudoElement(node: any): node is Pseudo;

    /**
     * Checks wether the node is, specifically, a pseudo class instead of
     * pseudo element.
     */
    function isPseudoClass(node: any): node is Pseudo;


    interface Tag extends Namespace {
        type: "tag";
    }
    function tag(opts: NamespaceOptions): Tag;
    function isTag(node: any): node is Tag;

    interface Comment extends Base {
        type: "comment";
    }
    function comment(opts: NodeOptions): Comment;
    function isComment(node: any): node is Comment;

    interface Identifier extends Base {
        type: "id";
    }
    function id(opts: any): any;
    function isIdentifier(node: any): node is Identifier;

    interface Nesting extends Base {
        type: "nesting";
    }
    function nesting(opts: any): any;
    function isNesting(node: any): node is Nesting;

    interface String extends Base {
        type: "string";
    }
    function string(opts: NodeOptions): String;
    function isString(node: any): node is String;

    interface Universal extends Base {
        type: "universal";
    }
    function universal(opts?: NamespaceOptions): any;
    function isUniversal(node: any): node is Universal;
}
