# Copyright (c) 2025 Tatu Aalto
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software
# and associated documentation files (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge, publish, distribute,
# sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all copies or
# substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

from pathlib import Path

from mcp.server.fastmcp import FastMCP

from .config import get_config, logger, resolve_path
from .mcp_check import _format_report, _get_violation_fix, filter_violations, run_robocop
from .mcp_format import robocop_format

mcp = FastMCP("op-robocop-mcp")


@mcp.tool()
async def get_robocop_report(path: str | None) -> str:
    """
    Run RoboCop on the provided source code and return the report.

    Args:
        path (str | None): The path to folder or a file to analyze. If None, uses the
        current directory for analysis.

    Returns:
        str: The Robocop report in markdown format.

    Example if there is one Violation in path, which looks like this:
    Violation(
        file=WindowsPath('sample.robot'),
        line_number=2,
        end_line=2,
        column=1,
        end_column=15,
        severity='W',
        rule_id='DOC02',
        description="Missing documentation in 'this is a test' test case"
    )
    Then return value would look like this:
    # Robocop Report

    ## Violation for file sample.robot in line 2 rule DOC02

    description: Missing documentation in 'this is a test' test case
    start line: 2
    end line: 2
    start column: 1
    end column: 15
    file: C:\\path\\to\\sample.robot
    rule id: DOC02
    severity: WARNING

    All violations reported.

    """
    path_resolved = resolve_path(path)
    logger.info("Running Robocop check on path: '%s'", path_resolved)
    report = await run_robocop(path_resolved)
    filter_report = filter_violations(report)
    if not filter_report:
        logger.info("No violations found.")
        return "# Robocop Report\n\nNo violations found."
    logger.info("Dump to markdown...")
    markdown_lines = ["# Robocop Report", ""]
    for item in filter_report:
        markdown_lines.extend(_format_report(item))

    first_violation = filter_report[0] if filter_report else None
    if not first_violation:
        markdown_lines.append("No violations found.")
        return "\n".join(markdown_lines)
    config = get_config()
    proposed_fix = _get_violation_fix(first_violation, config)
    markdown_lines.extend(
        [
            "",
            "## Proposed fixe for violations",
            "",
            f"The following fix is proposed: {proposed_fix}",
        ],
    )
    if len(filter_report) < len(report):
        markdown_lines.append(f"\nand {len(report) - len(filter_report)} more violations not shown.")
    else:
        markdown_lines.append("\nAll violations reported.")
    return "\n".join(markdown_lines)


@mcp.tool()
async def run_robocop_format(path: str | None) -> str:
    """Runs RoboCop formatter on the given path or folder.

    Args:
        path (str | None): The path to folder or a file to format. If None, uses the
        current directory for analysis.
    Returns:
        str: A summary of the operation.
    """
    path_resolved = resolve_path(path)
    logger.info("Running Robocop format on path: '%s'", path_resolved)
    return await robocop_format(Path(path_resolved))


def main() -> None:
    "Main to run the robocop-mcp server."
    logger.info("Starting OP Robocop MCP...")
    config = get_config()
    if config.robocopmcp_config_file:
        logger.info("With %s file.", config.robocopmcp_config_file)
    mcp.run(transport="stdio")


if __name__ == "__main__":
    main()
