<commit_before><commit_msg>Added RoutingPresenter.<commit_after>﻿using System;
using System.Linq;
using Silphid.Extensions;
using UnityEngine;

namespace Silphid.Showzup
{
    public class RoutingPresenter : MonoBehaviour, IPresenter
    {
        public GameObject[] SiblingPresenters = new GameObject[0];
        private IPresenter[] _siblingPresenters;
        
        public bool CanPresent(object input, Options options = null) =>
            true;

        internal void Start()
        {
            if (SiblingPresenters == null || SiblingPresenters.Length == 0)
                throw new NotSupportedException();

            _siblingPresenters = SiblingPresenters
                .Select(go =>
                {
                    var presenters = go
                        .GetComponents<IPresenter>()
                        .Where(presenter => !ReferenceEquals(presenter, this))
                        .ToArray();
                    
                    if (presenters.Length != 1)
                        throw new InvalidOperationException($"GameObject {go.name} should have one and only one IPresenter component.");
                    
                    return presenters.First();
                })
                .ToArray();
        }

        private IPresenter GetValidSiblingPresenter(object input, Options options = null) =>
            _siblingPresenters.FirstOrDefault(x => x.CanPresent(input, options));

        private IPresenter GetAncestorPresenter() =>
            this.Ancestors<RoutingPresenter>().FirstOrDefault();
        
        public IObservable<IView> Present(object input, Options options = null)
        {
            if (options?.Target == null)
                throw new InvalidOperationException("RoutingPresenter requires options to specify a Target variant.");
            
            var presenter = GetValidSiblingPresenter(input, options) ?? GetAncestorPresenter();
            if (presenter == null)
                throw new InvalidOperationException($"Failed to resolve routing for target: {options.Target}");

            return presenter.Present(input, options);
        }
    }
}
{'fraction_non_alphanumeric': 0.08395522388059702, 'fraction_numerical': 0.0013992537313432835, 'mean_word_length': 1.922343324250681, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 12, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6344023', 'n_tokens_mistral': 522, 'n_tokens_neox': 509, 'n_words': 126}