import dataclasses
import typing
from task.parsers.base import RequestParserBase

from task.parsers.callback import CallbackParser, CallbackParameter
from task.parsers.cmd_args import CommandLineArgumentParser
from task.parsers.objects import ObjectListParser, ObjectParameter
from task.parsers.freetext import FreeTextInputParser


@dataclasses.dataclass
class TaskConfiguration:
    callback: CallbackParameter
    cmd_args: typing.List[typing.Dict]
    objects: typing.List[ObjectParameter]
    input: str

    @property
    def json(self):
        return {
            "callback": dataclasses.asdict(self.callback),
            "cmd_args": self.cmd_args,
            "objects": [dataclasses.asdict(obj) for obj in self.objects],
            "input": self.input,
        }


class RequestParser(RequestParserBase):
    def __init__(self):
        super().__init__()

        self.add_argument("callback", type=dict)
        self.add_argument("input")
        self.add_argument("objects")
        self.add_argument("cmd_args")

        self.__callback_parser = CallbackParser("callback")
        self.__cmd_args_parser = CommandLineArgumentParser("cmd_args")
        self.__objects_parser = ObjectListParser("objects")
        self.__freetext_parser = FreeTextInputParser("input")

    def validate(self, request):
        self.__callback_parser.validate(request)
        self.__cmd_args_parser.validate(request)
        self.__objects_parser.validate(request)
        self.__freetext_parser.validate(request)

    def parse(self, request):
        request = self.parse_args()

        return TaskConfiguration(
            callback=self.__callback_parser.parse(request),
            cmd_args=self.__cmd_args_parser.parse(request),
            objects=self.__objects_parser.parse(request),
            input=self.__freetext_parser.parse(request),
        )
