import tempfile
import unittest
from pathlib import Path
from unittest.mock import patch

from app.fire_config import FIRE_MODEL
from app.provider_plan import plan
from app.inference_profiles import render_cfg


def base_spec():
    return dict(server_id='s',source_id='c',store=False,active_learning=False,
                scenarios='off',tracking={'enabled':True})


class FirePathTest(unittest.TestCase):
    def test_fire_coexists_with_pose_and_crowd(self):
        value=base_spec()
        value.update(
            fall={'enabled':True},
            fight={'enabled':True},
            intrusion={'enabled':True},
            loitering={'enabled':True},
            fire={'enabled':True,'scenario':{'enabled':True}},
            crowd={'enabled':True})
        planned=plan(value)
        self.assertEqual(planned.person_owner,'pose')
        self.assertEqual([p.key for p in planned.providers],['pose','fire','crowd'])
        self.assertEqual(set(planned.requested_scenarios),
                         {'INTRUSION','LOITERING','FALL','FIGHT','FIRE','CROWD'})

    def test_fire_only_plan(self):
        value=base_spec()
        value['tracking']={'enabled':False}
        value['fire']={'enabled':True,'scenario':{'enabled':True}}
        planned=plan(value)
        self.assertEqual([p.key for p in planned.providers],['fire'])
        self.assertEqual(planned.providers[0].model,FIRE_MODEL)

    def test_fire_cfg_can_use_unique_component_key(self):
        with tempfile.TemporaryDirectory() as root, patch(
                'app.inference_profiles._CFG_OUTPUT_DIR',root):
            cfg=Path(render_cfg('s','det',FIRE_MODEL,component_key='fire')).read_text()
            self.assertIn('CreateContextraFireProcessor',cfg)
            self.assertIn('input_tensor_from_meta',cfg)

    def test_model_class_contract(self):
        from model_tooling.manifests import make_input,ASSETS,ContractError
        key='fire-smoke-medium-v110-strict-v1';asset=ASSETS[key]
        with patch('model_tooling.manifests.fingerprints',
                   return_value={k:asset[k] for k in ('size_bytes','sha256','md5')}):
            value=make_input(key,Path('/tmp')/asset['filename'])
            self.assertEqual(value['contract']['class_mapping'],
                             {0:'smoke_visible',1:'flame_visible'})
            with self.assertRaises(ContractError):
                make_input('medium',Path('/tmp')/asset['filename'])


if __name__=='__main__':
    unittest.main()
