import unittest,tempfile,json,shutil,subprocess,hashlib,sys
from pathlib import Path
ROOT=Path(__file__).parent
class Gates(unittest.TestCase):
 def setUp(self):
  self.tmp=tempfile.TemporaryDirectory(dir=ROOT);self.r=Path(self.tmp.name)
  for n in ['prepare_target.py','bind_probe.py']:shutil.copy(ROOT/n,self.r/n)
  self.m={'max_source_field_utf8_bytes':711286,'source_sha256':'s','files':{'sql/01_schema.sql':{'sha256':'schema'},'column-mapping.json':{'sha256':'columns'}}};self.write('manifest.json',self.m)
 def tearDown(self):self.tmp.cleanup()
 def write(self,n,v):
  p=self.r/n;p.parent.mkdir(exist_ok=True);p.write_text(json.dumps(v));return p
 def prepare(self,app='',tbs='',probe=''):
  return subprocess.run([sys.executable,str(self.r/'prepare_target.py')],input='\n'.join(['','','','',tbs,app,probe,'',shutil.which('true')])+'\n',text=True,capture_output=True)
 def test_default_binding_and_no_overwrite(self):
  result=self.prepare();self.assertEqual(result.returncode,0,result.stderr)
  cfg=json.loads((self.r/'private/import.private.json').read_text());self.assertEqual(cfg['isolationProbeTable'],'FOODSAFE2_PROBE.Z_CAP_VALUES');self.assertEqual(cfg['user'],'FOODSAFE2_APP');self.assertEqual(cfg['expectedTablespace'],'FOODSAFE2_TBS')
  self.assertNotEqual(self.prepare().returncode,0)
 def test_first_accounts_blocked(self):
  for args in [{'app':'FOODSAFE_APP'},{'tbs':'FOODSAFE_TBS'},{'probe':'FOODSAFE1_PROBE'}]:
   self.assertNotEqual(self.prepare(**args).returncode,0);self.assertFalse((self.r/'private').exists())
 def test_dynamic_two_clones_and_wrong_probe(self):
  cfg={'user':'FOODSAFE2_APP','expectedInstance':'I','expectedBuild':'B','port':15236,'host':'127.0.0.1','expectedTablespace':'FOODSAFE2_TBS','isolationProbeTable':'FOODSAFE2_PROBE.Z_CAP_VALUES'}
  cp=self.write('connection.json',cfg);self.write('column-mapping.json',[{'TABLE_NAME':x,'EXTRA':'auto_increment','TARGET_IDENTITY_SEED':'5'} for x in ['a','b']])
  p={'large_field_bytes':711321,'passed':True,'target_user':cfg['user'],'instance':'I','build':'B','port':15236,'host':cfg['host'],'tablespace':cfg['expectedTablespace'],'manifest_sha256':hashlib.sha256((self.r/'manifest.json').read_bytes()).hexdigest(),'source_sha256':'s','schema_sha256':'schema','column_mapping_sha256':'columns','clone_tests':[{'table':x,'passed':True,'seed':'5','generated_next':'5'} for x in ['a','b']],'probe_user':'FOODSAFE2_PROBE','isolation_probe_table':cfg['isolationProbeTable'],'isolation_probe_exists':True}
  pp=self.write('probe.json',p)
  def run():return subprocess.run([sys.executable,str(self.r/'bind_probe.py'),str(cp),str(pp)],capture_output=True)
  self.assertEqual(run().returncode,0)
  for change in [{'isolation_probe_exists':False},{'isolation_probe_table':'FS1_PROBE.PROBE_FINAL_TEXT'},{'clone_tests':p['clone_tests'][:1]},{'host':'other'},{'large_field_bytes':710031}]:
   self.write('probe.json',{**p,**change});self.assertNotEqual(run().returncode,0)
if __name__=='__main__':unittest.main()
