# SPDX-License-Identifier: Apache-2.0
# Copyright 2024 The Meson development team

from __future__ import annotations

import difflib
import re
import typing as T
from configparser import ConfigParser, MissingSectionHeaderError, ParsingError
from copy import deepcopy
from dataclasses import dataclass, field, fields, asdict
from pathlib import Path
import sys

from . import mparser
from .mesonlib import MesonException, pathname_sort_key
from .ast.postprocess import AstConditionLevel
from .ast.printer import RawPrinter
from .ast.visitor import FullAstVisitor
from .environment import build_filename

if T.TYPE_CHECKING:
    import argparse
    from typing_extensions import Literal


class DefaultConfigParser(ConfigParser):

    def __init__(self, delimiters: T.Tuple[str, ...] = ('=', ':')):
        super().__init__(delimiters=delimiters, interpolation=None)

    def read_default(self, filename: Path) -> None:
        if not filename.exists():
            raise MesonException(f'Configuration file {filename} not found')
        try:
            super().read(filename, encoding='utf-8')
        except MissingSectionHeaderError:
            self.read_string(f'[{self.default_section}]\n' + filename.read_text(encoding='utf-8'))

    def getstr(self, section: str, key: str, fallback: T.Optional[str] = None) -> T.Optional[str]:
        value: T.Optional[str] = self.get(section, key, fallback=fallback)
        if value:
            value = value.strip('"').strip("'")
        return value


def match_path(filename: str, pattern: str) -> bool:
    '''recursive glob match for editorconfig sections'''
    index = 0
    num_ranges: T.List[T.Tuple[int, int]] = []

    def curl_replace(m: re.Match) -> str:
        nonlocal index

        if '\\.\\.' in m[1]:
            index += 1
            low, high = m[1].split('\\.\\.')
            num_ranges.append((int(low), int(high)))
            return f'(?P<num{index}>-?[0-9]+)'
        else:
            return T.cast(str, m[1].replace(',', '|'))

    pattern_re = pattern.replace('.', '\\.')
    pattern_re = re.sub(r'(?<!\\)\?', '.', pattern_re)  # ? -> .
    pattern_re = re.sub(r'(?<![\\\*])\*(?!\*)', '([^/]*)', pattern_re)  # * -> ([^/]*)
    pattern_re = re.sub(r'(?<!\\)\*\*', '(.*)', pattern_re)  # ** -> (.*)
    pattern_re = re.sub(r'(?<!\\)\[!(.*?[^\\])\]', r'([^\1])', pattern_re)  # [!name] -> [^name]
    pattern_re = re.sub(r'(?<!\\)\{(.*?[^\\])}', curl_replace, pattern_re)  # {}
    if pattern.startswith('/'):
        pattern_re = '^' + pattern_re
    pattern_re += '$'

    m = re.search(pattern_re, filename)
    if m is None:
        return False

    for i in range(index):
        try:
            val = int(m[f'num{i+1}'])
            if not num_ranges[i][0] <= val <= num_ranges[i][1]:
                return False
        except ValueError:
            return False

    return True


@dataclass
class EditorConfig:

    indent_style: T.Optional[Literal['space', 'tab']] = field(default=None, metadata={'getter': DefaultConfigParser.get})
    indent_size: T.Optional[int] = field(default=None, metadata={'getter': DefaultConfigParser.getint})
    tab_width: T.Optional[int] = field(default=None, metadata={'getter': DefaultConfigParser.getint})
    end_of_line: T.Optional[Literal['lf', 'cr', 'crlf']] = field(default=None, metadata={'getter': DefaultConfigParser.get})
    charset: T.Optional[Literal['latin1', 'utf-8', 'utf-8-bom', 'utf-16be', 'utf-16le']] = field(default=None, metadata={'getter': DefaultConfigParser.get})
    trim_trailing_whitespace: T.Optional[bool] = field(default=None, metadata={'getter': DefaultConfigParser.getboolean})
    insert_final_newline: T.Optional[bool] = field(default=None, metadata={'getter': DefaultConfigParser.getboolean})
    max_line_length: T.Optional[T.Union[Literal['off'], int]] = field(default=None, metadata={'getter': DefaultConfigParser.get})


@dataclass
class FormatterConfig:

    # Config keys compatible with muon
    max_line_length: T.Optional[int] = field(
        default=None,
        metadata={'getter': DefaultConfigParser.getint,
                  'default': 80,
                  })
    indent_by: T.Optional[str] = field(
        default=None,
        metadata={'getter': DefaultConfigParser.getstr,
                  'default': '    ',
                  })
    space_array: T.Optional[bool] = field(
        default=None,
        metadata={'getter': DefaultConfigParser.getboolean,
                  'default': False,
                  })
    kwargs_force_multiline: T.Optional[bool] = field(
        default=None,  # kwa_ml
        metadata={'getter': DefaultConfigParser.getboolean,
                  'default': False,
                  })
    wide_colon: T.Optional[bool] = field(
        default=None,
        metadata={'getter': DefaultConfigParser.getboolean,
                  'default': False,
                  })
    no_single_comma_function: T.Optional[bool] = field(
        default=None,
        metadata={'getter': DefaultConfigParser.getboolean,
                  'default': False,
                  })

    # Additional config keys
    end_of_line: T.Optional[Literal['cr', 'lf', 'crlf', 'native']] = field(
        default=None,
        metadata={'getter': DefaultConfigParser.getstr,
                  'default': 'native',
                  })
    indent_before_comments: T.Optional[str] = field(
        default=None,
        metadata={'getter': DefaultConfigParser.getstr,
                  'default': '  ',
                  })
    simplify_string_literals: T.Optional[bool] = field(
        default=None,
        metadata={'getter': DefaultConfigParser.getboolean,
                  'default': True,
                  })
    insert_final_newline: T.Optional[bool] = field(
        default=None,
        metadata={'getter': DefaultConfigParser.getboolean,
                  'default': True,
                  })
    tab_width: T.Optional[int] = field(
        default=None,
        metadata={'getter': DefaultConfigParser.getint,
                  'default': 4,
                  }
    )
    sort_files: T.Optional[bool] = field(
        default=None,
        metadata={'getter': DefaultConfigParser.getboolean,
                  'default': False,
                  })
    group_arg_value: T.Optional[bool] = field(
        default=None,
        metadata={'getter': DefaultConfigParser.getboolean,
                  'default': False,
                  })
    use_editor_config: T.Optional[bool] = field(
        default=None,
        metadata={'getter': DefaultConfigParser.getboolean,
                  'default': False,
                  })

    @classmethod
    def default(cls) -> FormatterConfig:
        defaults = {f.name: f.metadata['default'] for f in fields(cls)}
        return cls(**defaults)

    def update(self, config: FormatterConfig) -> FormatterConfig:
        """Returns copy of self updated with other config"""
        new_config = deepcopy(self)
        for key, value in asdict(config).items():
            if value is not None:
                setattr(new_config, key, value)
        return new_config

    def with_editorconfig(self, editorconfig: EditorConfig) -> FormatterConfig:
        """Returns copy of self updated with editorconfig"""
        config = deepcopy(self)

        if editorconfig.indent_style == 'space':
            indent_size = editorconfig.indent_size or 4
            config.indent_by = indent_size * ' '
        elif editorconfig.indent_style == 'tab':
            config.indent_by = '\t'
        elif editorconfig.indent_size:
            config.indent_by = editorconfig.indent_size * ' '

        if editorconfig.max_line_length == 'off':
            config.max_line_length = 0
        elif editorconfig.max_line_length:
            config.max_line_length = int(editorconfig.max_line_length)

        if editorconfig.end_of_line:
            config.end_of_line = editorconfig.end_of_line
        if editorconfig.insert_final_newline:
            config.insert_final_newline = editorconfig.insert_final_newline
        if editorconfig.tab_width:
            config.tab_width = editorconfig.tab_width

        return config

    @property
    def newline(self) -> T.Optional[str]:
        if self.end_of_line == 'crlf':
            return '\r\n'
        if self.end_of_line == 'lf':
            return '\n'
        if self.end_of_line == 'cr':
            return '\r'
        return None


class MultilineArgumentDetector(FullAstVisitor):

    def __init__(self, config: FormatterConfig):
        self.config = config
        self.is_multiline = False

    def enter_node(self, node: mparser.BaseNode) -> None:
        if node.whitespaces and '#' in node.whitespaces.value:
            self.is_multiline = True

        elif isinstance(node, mparser.StringNode) and node.is_multiline:
            self.is_multiline = True

    def visit_ArgumentNode(self, node: mparser.ArgumentNode) -> None:
        if node.is_multiline:
            self.is_multiline = True

        nargs = len(node)
        if nargs and nargs == len(node.commas):
            self.is_multiline = True

        if self.is_multiline:
            return

        if self.config.kwargs_force_multiline and node.kwargs:
            self.is_multiline = True

        super().visit_ArgumentNode(node)


class MultilineParenthesesDetector(FullAstVisitor):

    def __init__(self) -> None:
        self.last_whitespaces: T.Optional[mparser.WhitespaceNode] = None

    def enter_node(self, node: mparser.BaseNode) -> None:
        self.last_whitespaces = None

    def exit_node(self, node: mparser.BaseNode) -> None:
        if node.whitespaces and node.whitespaces.value:
            self.last_whitespaces = node.whitespaces


class TrimWhitespaces(FullAstVisitor):

    def __init__(self, config: FormatterConfig):
        self.config = config

        self.in_block_comments = False
        self.in_arguments = 0
        self.indent_comments = ''

    def visit_default_func(self, node: mparser.BaseNode) -> None:
        self.enter_node(node)
        node.whitespaces.accept(self)

    def enter_node(self, node: mparser.BaseNode) -> None:
        if isinstance(node, mparser.WhitespaceNode):
            return
        if not node.whitespaces:
            # Ensure every node has a whitespace node
            node.whitespaces = mparser.WhitespaceNode(mparser.Token('whitespace', node.filename, 0, 0, 0, (0, 0), ''))
            node.whitespaces.condition_level = node.condition_level

    def exit_node(self, node: mparser.BaseNode) -> None:
        pass

    def move_whitespaces(self, from_node: mparser.BaseNode, to_node: mparser.BaseNode) -> None:
        to_node.whitespaces.value = from_node.whitespaces.value + to_node.whitespaces.value
        to_node.whitespaces.is_continuation = from_node.whitespaces.is_continuation
        from_node.whitespaces = None
        to_node.whitespaces.accept(self)

    def add_space_after(self, node: mparser.BaseNode) -> None:
        if not node.whitespaces.value:
            node.whitespaces.value = ' '
        elif '#' not in node.whitespaces.value:
            node.whitespaces.value = ' '

    def add_nl_after(self, node: mparser.BaseNode, force: bool = False) -> None:
        if not node.whitespaces.value:
            node.whitespaces.value = '\n'
        elif force and not node.whitespaces.value.endswith('\n'):
            node.whitespaces.value += '\n'

    def dedent(self, value: str) -> str:
        if value.endswith(self.config.indent_by):
            value = value[:-len(self.config.indent_by)]
        return value

    def sort_arguments(self, node: mparser.ArgumentNode) -> None:
        def sort_key(arg: mparser.BaseNode) -> tuple[tuple[bool, tuple[int | str, ...]], ...]:
            if isinstance(arg, mparser.StringNode):
                val = arg.raw_value
            else:
                val = getattr(node, 'value', '')
            return pathname_sort_key(val)

        node.arguments.sort(key=sort_key)

    def visit_EmptyNode(self, node: mparser.EmptyNode) -> None:
        self.enter_node(node)
        self.in_block_comments = True
        node.whitespaces.accept(self)
        self.in_block_comments = False

    def visit_WhitespaceNode(self, node: mparser.WhitespaceNode) -> None:
        lines = node.value.splitlines(keepends=True)
        node.value = ''
        in_block_comments = self.in_block_comments
        with_comments = ['#' in line for line in lines] + [False]
        for i, line in enumerate(lines):
            has_nl = line.endswith('\n')
            line = line.strip()
            if line.startswith('\\'):
                node.value += ' '  # add space before \
                node.is_continuation = True
            elif line.startswith('#'):
                if not in_block_comments:
                    node.value += self.config.indent_before_comments
                else:
                    node.value += self.indent_comments
            node.value += line
            if has_nl and (line or with_comments[i+1] or not self.in_arguments):
                node.value += '\n'
            in_block_comments = True
        if node.value.endswith('\n'):
            node.value += self.indent_comments
            if node.is_continuation:
                node.value += self.config.indent_by

    def visit_SymbolNode(self, node: mparser.SymbolNode) -> None:
        super().visit_SymbolNode(node)
        if node.value in "([{" and node.whitespaces.value == '\n':
            node.whitespaces.value = ''
        node.whitespaces.accept(self)

    def visit_StringNode(self, node: mparser.StringNode) -> None:
        self.enter_node(node)

        if self.config.simplify_string_literals:
            if node.is_multiline and not any(x in node.value for x in ['\n', "'"]):
                node.is_multiline = False
                node.value = node.escape()

            if node.is_fstring and '@' not in node.value:
                node.is_fstring = False

        node.whitespaces.accept(self)

    def visit_UnaryOperatorNode(self, node: mparser.UnaryOperatorNode) -> None:
        super().visit_UnaryOperatorNode(node)
        self.move_whitespaces(node.value, node)

    def visit_NotNode(self, node: mparser.NotNode) -> None:
        super().visit_UnaryOperatorNode(node)
        if not node.operator.whitespaces.value:
            node.operator.whitespaces.value = ' '
        self.move_whitespaces(node.value, node)

    def visit_BinaryOperatorNode(self, node: mparser.BinaryOperatorNode) -> None:
        super().visit_BinaryOperatorNode(node)
        self.add_space_after(node.left)
        self.add_space_after(node.operator)
        self.move_whitespaces(node.right, node)

    def visit_ArrayNode(self, node: mparser.ArrayNode) -> None:
        super().visit_ArrayNode(node)
        self.move_whitespaces(node.rbracket, node)

        if node.lbracket.whitespaces.value:
            node.args.is_multiline = True
        if node.args.arguments and not node.args.is_multiline and self.config.space_array:
            self.add_space_after(node.lbracket)
            self.add_space_after(node.args)
        if not node.args.arguments:
            self.move_whitespaces(node.lbracket, node.args)

    def visit_DictNode(self, node: mparser.DictNode) -> None:
        super().visit_DictNode(node)
        self.move_whitespaces(node.rcurl, node)

        if node.lcurl.whitespaces.value:
            node.args.is_multiline = True

    def visit_CodeBlockNode(self, node: mparser.CodeBlockNode) -> None:
        self.enter_node(node)
        if node.pre_whitespaces:
            self.in_block_comments = True
            node.pre_whitespaces.accept(self)
            self.in_block_comments = False
        else:
            node.pre_whitespaces = mparser.WhitespaceNode(mparser.Token('whitespace', node.filename, 0, 0, 0, (0, 0), ''))
        node.pre_whitespaces.block_indent = True

        for i in node.lines:
            i.accept(self)
        self.exit_node(node)

        if node.lines:
            self.move_whitespaces(node.lines[-1], node)
        else:
            node.whitespaces.value = node.pre_whitespaces.value + node.whitespaces.value
            node.pre_whitespaces.value = ''
            self.in_block_comments = True
            node.whitespaces.accept(self)
            self.in_block_comments = False

        if node.condition_level == 0 and self.config.insert_final_newline:
            self.add_nl_after(node, force=True)

        indent = node.condition_level * self.config.indent_by
        if indent and node.lines:
            node.pre_whitespaces.value += indent
        for line in node.lines[:-1]:
            line.whitespaces.value += indent

    def visit_IndexNode(self, node: mparser.IndexNode) -> None:
        super().visit_IndexNode(node)
        self.move_whitespaces(node.rbracket, node)

    def visit_MethodNode(self, node: mparser.MethodNode) -> None:
        super().visit_MethodNode(node)
        self.move_whitespaces(node.rpar, node)

        if node.lpar.whitespaces.value:
            node.args.is_multiline = True

    def visit_FunctionNode(self, node: mparser.FunctionNode) -> None:
        if node.func_name.value == 'files':
            if self.config.sort_files:
                self.sort_arguments(node.args)

            if len(node.args.arguments) == 1 and not node.args.kwargs:
                arg = node.args.arguments[0]
                if isinstance(arg, mparser.ArrayNode):
                    if not arg.lbracket.whitespaces or not arg.lbracket.whitespaces.value.strip():
                        # files([...]) -> files(...)
                        node.args = arg.args

        super().visit_FunctionNode(node)
        self.move_whitespaces(node.rpar, node)

        if node.lpar.whitespaces.value:
            node.args.is_multiline = True

    def visit_AssignmentNode(self, node: mparser.AssignmentNode) -> None:
        super().visit_AssignmentNode(node)
        self.add_space_after(node.var_name)
        self.add_space_after(node.operator)
        self.move_whitespaces(node.value, node)

    def visit_ForeachClauseNode(self, node: mparser.ForeachClauseNode) -> None:
        super().visit_ForeachClauseNode(node)
        self.add_space_after(node.foreach_)
        self.add_space_after(node.varnames[-1])
        for comma in node.commas:
            self.add_space_after(comma)
        self.add_space_after(node.colon)

        node.block.whitespaces.value += node.condition_level * self.config.indent_by
        node.block.whitespaces.block_indent = True

        self.move_whitespaces(node.endforeach, node)

    def visit_IfClauseNode(self, node: mparser.IfClauseNode) -> None:
        super().visit_IfClauseNode(node)
        self.move_whitespaces(node.endif, node)

        for if_node in node.ifs:
            if_node.whitespaces.value += node.condition_level * self.config.indent_by
        if isinstance(node.elseblock, mparser.ElseNode):
            node.elseblock.whitespaces.value += node.condition_level * self.config.indent_by

    def visit_IfNode(self, node: mparser.IfNode) -> None:
        super().visit_IfNode(node)
        self.add_space_after(node.if_)
        self.in_block_comments = True
        self.move_whitespaces(node.block, node)
        self.in_block_comments = False
        node.whitespaces.condition_level = node.condition_level + 1
        node.whitespaces.block_indent = True

    def visit_ElseNode(self, node: mparser.ElseNode) -> None:
        super().visit_ElseNode(node)
        self.in_block_comments = True
        self.move_whitespaces(node.block, node)
        self.in_block_comments = False
        node.whitespaces.condition_level = node.condition_level + 1
        node.whitespaces.block_indent = True

    def visit_TernaryNode(self, node: mparser.TernaryNode) -> None:
        super().visit_TernaryNode(node)
        self.add_space_after(node.condition)
        self.add_space_after(node.questionmark)
        self.add_space_after(node.trueblock)
        self.add_space_after(node.colon)
        self.move_whitespaces(node.falseblock, node)

    def visit_ArgumentNode(self, node: mparser.ArgumentNode) -> None:
        if not node.is_multiline:
            ml_detector = MultilineArgumentDetector(self.config)
            node.accept(ml_detector)
            if ml_detector.is_multiline:
                node.is_multiline = True

        self.in_arguments += 1
        super().visit_ArgumentNode(node)
        self.in_arguments -= 1

        if not node.arguments and not node.kwargs:
            node.whitespaces.accept(self)
            return

        last_node: mparser.BaseNode
        has_trailing_comma = len(node.commas) == len(node.arguments) + len(node.kwargs)
        if has_trailing_comma:
            last_node = node.commas[-1]
        elif node.kwargs:
            for last_node in node.kwargs.values():
                pass
        else:
            last_node = node.arguments[-1]

        self.move_whitespaces(last_node, node)

        if not node.is_multiline and '#' not in node.whitespaces.value:
            node.whitespaces.value = ''

    def visit_ParenthesizedNode(self, node: mparser.ParenthesizedNode) -> None:
        self.enter_node(node)

        if node.lpar.whitespaces and '#' in node.lpar.whitespaces.value:
            node.is_multiline = True

        elif not node.is_multiline:
            ml_detector = MultilineParenthesesDetector()
            node.inner.accept(ml_detector)
            if ml_detector.last_whitespaces and '\n' in ml_detector.last_whitespaces.value:
                # We keep it multiline if last parenthesis is on a separate line
                node.is_multiline = True

        if node.is_multiline:
            self.indent_comments += self.config.indent_by

        node.lpar.accept(self)
        node.inner.accept(self)

        if node.is_multiline:
            node.inner.whitespaces.value = self.dedent(node.inner.whitespaces.value)
            self.indent_comments = self.dedent(self.indent_comments)
            self.add_nl_after(node.inner)
        else:
            node.inner.whitespaces = None

        node.rpar.accept(self)
        self.move_whitespaces(node.rpar, node)


class ArgumentFormatter(FullAstVisitor):

    def __init__(self, config: FormatterConfig):
        self.config = config
        self.level = 0
        self.indent_after = False
        self.is_function_arguments = False
        self.par_level = 0

    def add_space_after(self, node: mparser.BaseNode) -> None:
        if not node.whitespaces.value:
            node.whitespaces.value = ' '

    def add_nl_after(self, node: mparser.BaseNode, indent: int) -> None:
        if not node.whitespaces.value or node.whitespaces.value == ' ':
            node.whitespaces.value = '\n'
        indent_by = (node.condition_level + indent) * self.config.indent_by
        if indent_by:
            node.whitespaces.value = re.sub(rf'\n({self.config.indent_by})*', '\n' + indent_by, node.whitespaces.value)

    def visit_ArrayNode(self, node: mparser.ArrayNode) -> None:
        self.enter_node(node)
        if node.args.is_multiline:
            self.level += 1
            if node.args.arguments:
                self.add_nl_after(node.lbracket, indent=self.level)
        node.lbracket.accept(self)
        self.is_function_arguments = False
        node.args.accept(self)
        if node.args.is_multiline:
            self.level -= 1
        node.rbracket.accept(self)
        self.exit_node(node)

    def visit_DictNode(self, node: mparser.DictNode) -> None:
        self.enter_node(node)
        if node.args.is_multiline:
            self.level += 1
            if node.args.kwargs:
                self.add_nl_after(node.lcurl, indent=self.level)
        node.lcurl.accept(self)
        self.is_function_arguments = False
        node.args.accept(self)
        if node.args.is_multiline:
            self.level -= 1
        node.rcurl.accept(self)
        self.exit_node(node)

    def visit_MethodNode(self, node: mparser.MethodNode) -> None:
        self.enter_node(node)
        node.source_object.accept(self)
        is_cont = node.source_object.whitespaces and node.source_object.whitespaces.is_continuation
        if is_cont:
            self.level += 1
        if node.args.is_multiline:
            self.level += 1
            self.add_nl_after(node.lpar, indent=self.level)
        self.is_function_arguments = True
        node.args.accept(self)
        if node.args.is_multiline:
            self.level -= 1
        if is_cont:
            self.level -= 1
        self.exit_node(node)

    def visit_FunctionNode(self, node: mparser.FunctionNode) -> None:
        self.enter_node(node)
        if node.args.is_multiline:
            self.level += 1
            self.add_nl_after(node.lpar, indent=self.level)
        self.is_function_arguments = True
        node.args.accept(self)
        if node.args.is_multiline:
            self.level -= 1
        self.exit_node(node)

    def visit_WhitespaceNode(self, node: mparser.WhitespaceNode) -> None:
        lines = node.value.splitlines(keepends=True)
        if lines:
            indent = (node.condition_level + self.level) * self.config.indent_by
            node.value = '' if node.block_indent else lines.pop(0)
            for line in lines:
                if '#' in line and not line.startswith(indent):
                    node.value += indent
                node.value += line
            if self.indent_after and node.value.endswith(('\n', self.config.indent_by)):
                node.value += indent

    def visit_ArgumentNode(self, node: mparser.ArgumentNode) -> None:
        is_function_arguments = self.is_function_arguments  # record it, because it may change when visiting children
        super().visit_ArgumentNode(node)

        for colon in node.colons:
            self.add_space_after(colon)

        if self.config.wide_colon:
            for key in node.kwargs:
                self.add_space_after(key)

        arguments_count = len(node.arguments) + len(node.kwargs)
        has_trailing_comma = node.commas and len(node.commas) == arguments_count
        if node.is_multiline:
            need_comma = True
            if arguments_count == 1 and is_function_arguments:
                need_comma = not self.config.no_single_comma_function

            if need_comma and not has_trailing_comma:
                comma = mparser.SymbolNode(mparser.Token('comma', node.filename, 0, 0, 0, (0, 0), ','))
                comma.condition_level = node.condition_level
                comma.whitespaces = mparser.WhitespaceNode(mparser.Token('whitespace', node.filename, 0, 0, 0, (0, 0), ''))
                node.commas.append(comma)
            elif has_trailing_comma and not need_comma:
                node.commas.pop(-1)

            arg_index = 0
            if self.config.group_arg_value:
                for arg in node.arguments[:-1]:
                    group_args = False
                    if isinstance(arg, mparser.StringNode) and arg.value.startswith('--') and arg.value != '--':
                        next_arg = node.arguments[arg_index + 1]
                        if isinstance(next_arg, mparser.StringNode) and not next_arg.value.startswith('--'):
                            group_args = True
                    if group_args:
                        # keep '--arg', 'value' on same line
                        self.add_space_after(node.commas[arg_index])
                    elif arg_index < len(node.commas):
                        self.add_nl_after(node.commas[arg_index], self.level + self.par_level)
                    arg_index += 1

            for comma in node.commas[arg_index:-1]:
                self.add_nl_after(comma, self.level + self.par_level)
            if node.arguments or node.kwargs:
                self.add_nl_after(node, self.level - 1)

        else:
            if has_trailing_comma and not (node.commas[-1].whitespaces and node.commas[-1].whitespaces.value):
                node.commas.pop(-1)

            for comma in node.commas:
                self.add_space_after(comma)

        self.exit_node(node)

    def visit_ParenthesizedNode(self, node: mparser.ParenthesizedNode) -> None:
        self.enter_node(node)
        if node.is_multiline:
            self.par_level += 1
            current_indent_after = self.indent_after
            self.indent_after = True
        node.lpar.accept(self)
        if node.is_multiline:
            self.add_nl_after(node.lpar, indent=self.level + self.par_level)
        node.inner.accept(self)
        if node.is_multiline:
            self.par_level -= 1
            self.indent_after = current_indent_after
        node.rpar.accept(self)
        self.exit_node(node)

    def visit_OrNode(self, node: mparser.OrNode) -> None:
        self.enter_node(node)
        node.left.accept(self)
        if self.par_level:
            self.add_nl_after(node.left, indent=self.level + self.par_level)
        node.operator.accept(self)
        node.right.accept(self)
        self.exit_node(node)

    def visit_AndNode(self, node: mparser.AndNode) -> None:
        self.enter_node(node)
        node.left.accept(self)
        if self.par_level:
            self.add_nl_after(node.left, indent=self.level + self.par_level)
        node.operator.accept(self)
        node.right.accept(self)
        self.exit_node(node)


class ComputeLineLengths(FullAstVisitor):

    def __init__(self, config: FormatterConfig, level: int):
        self.config = config
        self.lengths: T.List[int] = []
        self.length = 0
        self.argument_stack: T.List[mparser.ArgumentNode] = []
        self.level = level
        self.need_regenerate = False

    def visit_default_func(self, node: mparser.BaseNode) -> None:
        self.enter_node(node)
        assert hasattr(node, 'value')
        self.length += len(str(node.value))
        self.exit_node(node)

    def len(self, line: str) -> int:
        '''Compute line length, including tab stops'''
        parts = line.split('\t')
        line_length = len(parts[0])
        for p in parts[1:]:
            tab_length = ((self.length + line_length) % self.config.tab_width) or self.config.tab_width
            line_length += tab_length + len(p)
        return line_length

    def count_multiline(self, value: str) -> None:
        lines = value.splitlines(keepends=True)
        for line in lines:
            if line.endswith('\n'):
                self.lengths.append(self.length + self.len(line) - 1)
                self.length = 0
            else:
                self.length += self.len(line)

    def visit_WhitespaceNode(self, node: mparser.WhitespaceNode) -> None:
        self.count_multiline(node.value)

    def visit_EmptyNode(self, node: mparser.EmptyNode) -> None:
        self.enter_node(node)
        self.exit_node(node)

    def visit_NumberNode(self, node: mparser.NumberNode) -> None:
        self.enter_node(node)
        self.length += len(node.raw_value)
        self.exit_node(node)

    def visit_StringNode(self, node: mparser.StringNode) -> None:
        self.enter_node(node)
        if node.is_fstring:
            self.length += 1

        if node.is_multiline:
            self.length += 3
            self.count_multiline(node.value)
            self.length += 3
        else:
            self.length += self.len(node.raw_value) + 2

        self.exit_node(node)

    def visit_ContinueNode(self, node: mparser.ContinueNode) -> None:
        self.enter_node(node)
        self.length += len('continue')
        self.exit_node(node)

    def visit_BreakNode(self, node: mparser.BreakNode) -> None:
        self.enter_node(node)
        self.length += len('break')
        self.exit_node(node)

    def split_if_needed(self, node: mparser.ArgumentNode) -> None:
        if len(node) and not node.is_multiline and self.length > self.config.max_line_length:
            arg = self.argument_stack[self.level] if len(self.argument_stack) > self.level else node
            arg.is_multiline = True
            self.need_regenerate = True

    def visit_ArgumentNode(self, node: mparser.ArgumentNode) -> None:
        self.argument_stack.append(node)
        super().visit_ArgumentNode(node)
        self.split_if_needed(node)
        self.argument_stack.pop(-1)

    def visit_ArrayNode(self, node: mparser.ArrayNode) -> None:
        self.enter_node(node)
        node.lbracket.accept(self)
        node.args.accept(self)
        node.rbracket.accept(self)
        self.split_if_needed(node.args)  # split if closing bracket is too far
        self.exit_node(node)

    def visit_DictNode(self, node: mparser.DictNode) -> None:
        self.enter_node(node)
        node.lcurl.accept(self)
        node.args.accept(self)
        node.rcurl.accept(self)
        self.split_if_needed(node.args)  # split if closing bracket is too far
        self.exit_node(node)

    def visit_ParenthesizedNode(self, node: mparser.ParenthesizedNode) -> None:
        self.enter_node(node)
        node.lpar.accept(self)
        node.inner.accept(self)
        node.rpar.accept(self)
        if not node.is_multiline and self.length > self.config.max_line_length:
            node.is_multiline = True
            self.need_regenerate = True
        self.exit_node(node)


class SubdirFetcher(FullAstVisitor):

    def __init__(self, current_dir: Path, fetch_subprojects: bool):
        self.current_dir = current_dir
        self.fetch_subprojects = fetch_subprojects
        self.subdirs: T.List[Path] = []

    def visit_FunctionNode(self, node: mparser.FunctionNode) -> None:
        if self.fetch_subprojects and node.func_name.value == 'subproject':
            if node.args.arguments and isinstance(node.args.arguments[0], mparser.StringNode):
                subdir = node.args.arguments[0].value
                self.subdirs.append(self.current_dir / 'subprojects' / subdir)
        if node.func_name.value == 'subdir':
            if node.args.arguments and isinstance(node.args.arguments[0], mparser.StringNode):
                subdir = node.args.arguments[0].value
                self.subdirs.append(self.current_dir / subdir)
        super().visit_FunctionNode(node)


class Formatter:

    def __init__(self, configuration_file: T.Optional[Path], use_editor_config: bool, fetch_subdirs: bool, fetch_subprojects: bool = False):
        self.fetch_subdirs = fetch_subdirs
        self.fetch_subprojects = fetch_subprojects
        self.use_editor_config = use_editor_config
        self.config = self.load_configuration(configuration_file)
        self.current_config = self.config

        self.current_dir = Path()
        self.subdirs: T.List[Path] = []

    def load_editor_config(self, source_file: Path) -> EditorConfig:
        # See https://editorconfig.org/
        config = EditorConfig()

        if source_file == Path('STDIN'):
            raise MesonException('Using editorconfig with stdin requires --source-file-path argument')

        try:
            source_file_path = source_file.resolve()
        except FileNotFoundError:
            raise MesonException(f'Unable to resolve path for "{source_file}"')

        for p in source_file_path.parents:
            editorconfig_file = p / '.editorconfig'
            if not editorconfig_file.exists():
                continue

            cp = DefaultConfigParser(delimiters=('=',))
            cp.read_default(editorconfig_file)

            sections = [section for section in cp.sections() if match_path(source_file.as_posix(), section)]
            for f in fields(config):
                if getattr(cp, f.name, None) is not None:
                    continue  # value already set from higher file

                getter = f.metadata['getter']
                for section in sections:
                    try:
                        value = getter(cp, section, f.name, fallback=None)
                    except ValueError as e:
                        raise MesonException(f'Invalid type for key "{f.name}" in "{editorconfig_file}" file:\n{e}') from e
                    if value is not None:
                        setattr(config, f.name, value)

            # Root is not required except in the top level .editorconfig.
            if cp.getboolean(cp.default_section, 'root', fallback=False):
                break

        return config

    def load_configuration(self, configuration_file: T.Optional[Path]) -> FormatterConfig:
        config = FormatterConfig()
        if configuration_file:
            cp = DefaultConfigParser()
            try:
                cp.read_default(configuration_file)
            except ParsingError as e:
                raise MesonException(f'Unable to parse configuration file "{configuration_file}":\n{e}') from e

            extra_keys = sorted(set(cp.defaults()).difference(f.name for f in fields(config)))
            if extra_keys:
                raise MesonException(f'Unknown config keys: "{", ".join(extra_keys)}" in configuration file "{configuration_file}"')

            for f in fields(config):
                getter = f.metadata['getter']
                try:
                    value = getter(cp, cp.default_section, f.name, fallback=None)
                except ValueError as e:
                    raise MesonException(
                        f'Error parsing "{str(configuration_file)}", option "{f.name}", error: "{e!s}"')
                if value is not None:
                    setattr(config, f.name, value)

            if config.use_editor_config:
                self.use_editor_config = True

        return config

    def format(self, code: str, source_file: Path) -> str:
        self.current_dir = source_file.parent
        self.current_config = FormatterConfig.default()
        if self.use_editor_config:
            self.current_config = self.current_config.with_editorconfig(self.load_editor_config(source_file))
        self.current_config = self.current_config.update(self.config)

        ast = mparser.Parser(code, source_file.as_posix()).parse()
        if self.fetch_subdirs:
            subdir_fetcher = SubdirFetcher(self.current_dir, self.fetch_subprojects)
            ast.accept(subdir_fetcher)
            self.subdirs = subdir_fetcher.subdirs

        ast.accept(AstConditionLevel())
        for level in range(5):
            ast.accept(TrimWhitespaces(self.current_config))
            ast.accept(ArgumentFormatter(self.current_config))

            cll = ComputeLineLengths(self.current_config, level)
            ast.accept(cll)
            if not cll.need_regenerate:
                break

        printer = RawPrinter()
        ast.accept(printer)
        return printer.result


def add_arguments(parser: argparse.ArgumentParser) -> None:
    inplace_group = parser.add_mutually_exclusive_group()
    inplace_group.add_argument(
        '-q', '--check-only',
        action='store_true',
        help='silently exit with 1 if files would be modified by meson format'
    )
    inplace_group.add_argument(
        '-d', '--check-diff',
        action='store_true',
        default=False,
        help='exit with 1 and show diff if files would be modified by meson format'
    )
    inplace_group.add_argument(
        '-i', '--inplace',
        action='store_true',
        help='format files in-place'
    )
    parser.add_argument(
        '-r', '--recursive',
        action='store_true',
        help='recurse subdirs (requires --check-only, --check-diff or --inplace option)',
    )
    parser.add_argument(
        '-s', '--subprojects',
        action='store_true',
        help='recurse subprojects (requires --recursive)',
    )
    parser.add_argument(
        '-c', '--configuration',
        metavar='meson.format',
        type=Path,
        help='read configuration from meson.format'
    )
    parser.add_argument(
        '-e', '--editor-config',
        action='store_true',
        default=False,
        help='try to read configuration from .editorconfig'
    )
    parser.add_argument(
        '-o', '--output',
        type=Path,
        help='output file (implies having exactly one input)'
    )
    parser.add_argument(
        '--source-file-path',
        type=Path,
        help='path to use, when reading from stdin'
    )
    parser.add_argument(
        'sources',
        nargs='*',
        type=Path,
        help='meson source files'
    )

def get_meson_format(sources: T.List[Path]) -> T.Optional[Path]:
    for src_file in sources:
        for parent in src_file.resolve().parents:
            target = parent / 'meson.format'
            if target.is_file():
                return target
    return None

def run(options: argparse.Namespace) -> int:
    if options.output and len(options.sources) != 1:
        raise MesonException('--output argument implies having exactly one source file')
    if options.recursive and not (options.inplace or options.check_only or options.check_diff):
        raise MesonException('--recursive argument requires one of --inplace, --check-diff or --check-only')
    if options.subprojects and not options.recursive:
        raise MesonException('--subprojects argument requires --recursive option')

    from_stdin = len(options.sources) == 1 and options.sources[0].name == '-' and options.sources[0].parent == Path()
    if options.recursive and from_stdin:
        raise MesonException('--recursive argument is not compatible with stdin input')
    if options.inplace and from_stdin:
        raise MesonException('--inplace argument is not compatible with stdin input')
    if options.source_file_path and not from_stdin:
        raise MesonException('--source-file-path argument is only compatible with stdin input')
    if from_stdin and options.editor_config and not options.source_file_path:
        raise MesonException('using --editor-config with stdin input requires --source-file-path argument')

    sources: T.List[Path] = options.sources.copy() or [Path(build_filename)]

    if not options.configuration:
        options.configuration = get_meson_format(sources)

    formatter = Formatter(options.configuration, options.editor_config, options.recursive, options.subprojects)
    err = 0

    while sources:
        src_file = sources.pop(0)
        if src_file.is_dir():
            src_file = src_file / build_filename

        try:
            if from_stdin:
                src_file = options.source_file_path or Path('STDIN')  # used for error messages and introspection
                code = sys.stdin.read()
            else:
                code = src_file.read_text(encoding='utf-8')
        except IOError as e:
            raise MesonException(f'Unable to read from {src_file}') from e

        formatted = formatter.format(code, src_file)
        if options.recursive:
            sources.extend(formatter.subdirs)

        if options.inplace:
            try:
                with src_file.open('w', encoding='utf-8', newline=formatter.current_config.newline) as sf:
                    sf.write(formatted)
            except IOError as e:
                raise MesonException(f'Unable to write to {src_file}') from e
        elif options.check_only or options.check_diff:
            if code != formatted:
                err = 1
                if options.check_diff:
                    diff = difflib.unified_diff(code.splitlines(), formatted.splitlines(),
                                                str(src_file), str(src_file),
                                                '(original)', '(reformatted)',
                                                lineterm='')
                    print('\n'.join(diff))
                else:
                    break
        elif options.output:
            try:
                with options.output.open('w', encoding='utf-8', newline=formatter.current_config.newline) as of:
                    of.write(formatted)
            except IOError as e:
                raise MesonException(f'Unable to write to {options.output}') from e
        else:
            print(formatted, end='')

    return err

# TODO: remove empty newlines when more than N (2...)
# TODO: magic comment to prevent formatting
# TODO: split long lines on binary operators
# TODO: align series of assignments
# TODO: align comments
# TODO: move comments on long lines

# Differences from muon format:
# - By default, uses two spaces before comment, and added option for that
# - Muon will mix CRLF and LF on Windows files...
# - Support for end_of_line char
# - Support for max_line_length, end_of_line, insert_final_newline, tab_width in .editorconfig
# - Option to simplify string literals
# - Option to recognize and parse meson.build in subdirs
# - Correctly compute line length when using tabs
# - By default, arguments in files() are sorted naturally
# - Option to group '--arg', 'value' on same line in multiline arguments
