#include "sema.h"

namespace empathy::sema
{
    ptr< TemplateRule > GetTemplateRuleSet( const Context& c, const Value& tpl )
    {
        const auto& rules = c.env()->templateRuleSet()->rules();

        MatchSolution bestSol;
        ptr< TemplateRule > pBestRule;
        bool ambiguous = false;

        for( auto&& [s, rule] : Match( tpl.type(), rules ) )
        {
            if( !pBestRule || s > bestSol )
            {
                bestSol = s;
                pBestRule = rule;
                ambiguous = false;
                continue;
            }

            if( s < bestSol )
                continue;

            ambiguous = true;
        }

        // Let's not really worry about how to properly report this for now.
        if( ambiguous )
            throw runtime_error( "ambiguous template rule" );

        return pBestRule;
    }

    optional< Term > BuildTemplateSignature( const Context& c, const Value& tpl )
    {
        const auto pTemplateRuleSet = GetTemplateRuleSet( c, tpl );
        if( !pTemplateRuleSet )
            return nullopt;

        return pTemplateRuleSet->buildSignature( c, tpl );
    }
}
