import hashlib,json,tempfile,unittest
from pathlib import Path
from unittest.mock import patch
from deployment_kit import image_identity as ii, release
from deployment_kit.core import KitError

class ImageIdentityTests(unittest.TestCase):
    def test_classic(self):
        with patch.object(ii,'docker',return_value=(0,json.dumps({'Id':'sha256:old'}))):
            self.assertEqual(ii.resolve('tag','sha256:old'),'sha256:old')
    def test_manifest_config_proof(self):
        body=json.dumps({'config':{'digest':'sha256:old'}})
        actual='sha256:'+hashlib.sha256(body.encode()).hexdigest()
        desc={'Id':actual,'Descriptor':{'digest':actual,'mediaType':'application/vnd.oci.image.manifest.v1+json'}}
        with patch.object(ii,'docker',return_value=(0,json.dumps(desc))),patch.object(ii,'run',return_value=(0,body)):
            self.assertEqual(ii.resolve('tag','sha256:old'),actual)
            with self.assertRaises(KitError):ii.resolve('tag','sha256:wrong')
        with patch.object(ii,'docker',return_value=(0,json.dumps(desc))),patch.object(ii,'run',return_value=(0,body+' ')):
            with self.assertRaises(KitError):ii.resolve('tag','sha256:old')
    def test_query_failure_not_missing(self):
        with patch.object(ii,'docker',return_value=(1,'Cannot connect')):
            with self.assertRaises(KitError):ii.resolve('tag','old')
    def test_preloaded_never_loads(self):
        with tempfile.TemporaryDirectory() as td,patch.object(release,'resolve_image',return_value='runtime-id'),patch.object(release,'docker',side_effect=AssertionError('load')):
            self.assertEqual(release.prepare_images({'kind':'FULL','images':[{'service':'analytics','reference':'tag','id':'old','archive':'images.tar'}]},Path(td),Path(td),None),{'analytics':'runtime-id'})
    def test_config_reference_lookup(self):
        def docker(*args,**kw):
            if args[1]=='ls':return 0,'sha256:new'
            if args[-1]=='sha256:old':return 1,'No such image: sha256:old'
            return 0,json.dumps({'Id':'sha256:old'})
        with patch.object(ii,'docker',side_effect=docker):
            self.assertEqual(ii.resolve('sha256:old','sha256:old'),'sha256:old')
