from collections.abc import Callable
from typing import cast

import reactivex
from reactivex import (
    Observable,
)
from reactivex import (
    operators as ops,
)
from reactivex.scheduler import (
    ThreadPoolScheduler,
)

from labels.model.parser import Request
from labels.parsers.cataloger.dart.cataloger import (
    on_next_dart,
)
from labels.parsers.cataloger.dotnet.cataloger import (
    on_next_dotnet,
)
from labels.parsers.cataloger.golang.cataloger import (
    on_next_golang,
)
from labels.parsers.cataloger.java.cataloger import (
    on_next_java,
)
from labels.parsers.cataloger.javascript.cataloger import (
    on_next_javascript,
)
from labels.parsers.cataloger.php.cataloger import (
    on_next_php,
)
from labels.parsers.cataloger.python.cataloger import (
    on_next_python,
)
from labels.parsers.cataloger.ruby.cataloger import (
    on_next_ruby,
)
from labels.parsers.cataloger.swift.cataloger import (
    on_next_swift,
)


def handle_parser(
    scheduler: ThreadPoolScheduler,
) -> Callable[[Observable[str]], Observable[Request]]:
    def _apply_parsers(source: Observable[str]) -> Observable[Request]:
        def fanout(item: str) -> Observable[Request]:
            return cast(
                "Observable[Request]",
                reactivex.merge(
                    (on_next_python(reactivex.just(item, scheduler))),
                    (on_next_java(reactivex.just(item, scheduler))),
                    (on_next_javascript(reactivex.just(item, scheduler))),
                    (on_next_dotnet(reactivex.just(item, scheduler))),
                    (on_next_ruby(reactivex.just(item, scheduler))),
                    (on_next_php(reactivex.just(item, scheduler))),
                    (on_next_swift(reactivex.just(item, scheduler))),
                    (on_next_dart(reactivex.just(item, scheduler))),
                    (on_next_golang(reactivex.just(item, scheduler))),
                ),
            )

        return source.pipe(
            ops.flat_map(fanout),
        )

    return _apply_parsers
