# ------------------------------------------------------------------------
# RF-DETR
# Copyright (c) 2025 Roboflow. All Rights Reserved.
# Licensed under the Apache License, Version 2.0 [see LICENSE for details]
# ------------------------------------------------------------------------
"""LightningCLI entry point for RF-DETR training and evaluation.

Provides the ``rfdetr`` command with auto-generated subcommands::

    rfdetr fit     --config configs/rfdetr_base.yaml
    rfdetr validate --ckpt_path output/best.ckpt
    rfdetr test    --ckpt_path output/best.ckpt
    rfdetr predict --ckpt_path output/best.ckpt

Both ``RFDETRModelModule`` and ``RFDETRDataModule`` share the same ``(model_config, train_config)`` constructor
signature.  ``link_arguments`` eliminates the duplication so the user specifies each config group once; the datamodule
receives the same values automatically at parse time.
"""

from pytorch_lightning.cli import LightningArgumentParser, LightningCLI

from rfdetr.training.module_data import RFDETRDataModule
from rfdetr.training.module_model import RFDETRModelModule

_PARSER_KWARGS = {
    "prog": "rfdetr",
    "description": "RF-DETR command line interface.",
}


class RFDETRCli(LightningCLI):
    """LightningCLI subclass for RF-DETR training and evaluation.

    Wires ``RFDETRModelModule`` and ``RFDETRDataModule`` under a unified CLI, with argument linking that shares
    ``model_config`` and ``train_config`` between module and datamodule so the user only specifies them once.

    Auto-generated subcommands: ``fit``, ``validate``, ``test``, ``predict``.
    """

    def add_arguments_to_parser(self, parser: LightningArgumentParser) -> None:
        """Register argument links that share configs between module and datamodule.

        Linking ``model.model_config`` → ``data.model_config`` and ``model.train_config`` → ``data.train_config`` means
        the user specifies both config groups once; the datamodule receives the same values automatically.

        Args:
            parser: The jsonargparse ``LightningArgumentParser`` provided by
                ``LightningCLI``.
        """
        parser.link_arguments("model.model_config", "data.model_config", apply_on="parse")
        parser.link_arguments("model.train_config", "data.train_config", apply_on="parse")


def main() -> None:
    """Entry point for the ``rfdetr`` CLI.

    Constructs and runs ``RFDETRCli`` with ``RFDETRModelModule`` and ``RFDETRDataModule``.  Subcommands are auto-
    generated by ``LightningCLI``: ``fit``, ``validate``, ``test``, ``predict``.
    """
    RFDETRCli(RFDETRModelModule, RFDETRDataModule, parser_kwargs=_PARSER_KWARGS)


if __name__ == "__main__":
    main()
