"""
Unit tests for Flow configuration validation
"""

import unittest
import sys
import os
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))

from optrabot.config import Config
from optrabot.flowengine.flowconfig import Flow
from optrabot.tradetemplate.templatefactory import Template
from unittest.mock import Mock, patch


class ConfigFlowValidationTests(unittest.TestCase):
	"""Test cases for Flow template validation"""
	
	def setUp(self):
		"""Set up test fixtures"""
		self.config = Config()
		
	def test_flow_with_nonexistent_event_template(self):
		"""Test that flow is disabled when event template does not exist"""
		# Create a mock template
		mock_template = Mock(spec=Template)
		mock_template.name = 'ExistingTemplate'
		mock_template.is_enabled = Mock(return_value=True)
		
		self.config._templates = [mock_template]
		
		# Parse a flow with non-existent event template
		flow_data = {
			'name': 'Test Flow',
			'enabled': True,
			'event': {
				'type': 'early_exit',
				'template': 'NonExistentTemplate'
			},
			'actions': [
				{
					'send_notification': {
						'message': 'Test',
						'type': 'INFO'
					}
				}
			]
		}
		
		flow = self.config._parse_flow('test_flow', flow_data)
		
		self.assertIsNotNone(flow, 'Flow should be created')
		self.assertFalse(flow.enabled, 'Flow should be disabled when event template does not exist')
		
	def test_flow_with_disabled_event_template(self):
		"""Test that flow is disabled when event template is disabled"""
		# Create a disabled template
		mock_template = Mock(spec=Template)
		mock_template.name = 'DisabledTemplate'
		mock_template.is_enabled = Mock(return_value=False)
		
		self.config._templates = [mock_template]
		
		# Parse a flow with disabled event template
		flow_data = {
			'name': 'Test Flow',
			'enabled': True,
			'event': {
				'type': 'trade_opened',
				'template': 'DisabledTemplate'
			},
			'actions': []
		}
		
		flow = self.config._parse_flow('test_flow', flow_data)
		
		self.assertIsNotNone(flow, 'Flow should be created')
		self.assertFalse(flow.enabled, 'Flow should be disabled when event template is disabled')
		
	def test_flow_with_nonexistent_action_template(self):
		"""Test that flow is disabled when action template does not exist"""
		# Create a mock template for event
		mock_template = Mock(spec=Template)
		mock_template.name = 'EventTemplate'
		mock_template.is_enabled = Mock(return_value=True)
		
		self.config._templates = [mock_template]
		
		# Parse a flow with non-existent action template
		flow_data = {
			'name': 'Test Flow',
			'enabled': True,
			'event': {
				'type': 'early_exit',
				'template': 'EventTemplate'
			},
			'actions': [
				{
					'process_template': {
						'template': 'NonExistentActionTemplate',
						'amount': 2,
						'premium': 0.5
					}
				}
			]
		}
		
		flow = self.config._parse_flow('test_flow', flow_data)
		
		self.assertIsNotNone(flow, 'Flow should be created')
		self.assertFalse(flow.enabled, 'Flow should be disabled when action template does not exist')
		
	def test_flow_with_disabled_action_template(self):
		"""Test that flow is disabled when action template is disabled"""
		# Create templates
		event_template = Mock(spec=Template)
		event_template.name = 'EventTemplate'
		event_template.is_enabled = Mock(return_value=True)
		
		action_template = Mock(spec=Template)
		action_template.name = 'ActionTemplate'
		action_template.is_enabled = Mock(return_value=False)
		
		self.config._templates = [event_template, action_template]
		
		# Parse a flow with disabled action template
		flow_data = {
			'name': 'Test Flow',
			'enabled': True,
			'event': {
				'type': 'stop_loss_hit',
				'template': 'EventTemplate'
			},
			'actions': [
				{
					'process_template': {
						'template': 'ActionTemplate',
						'amount': 1,
						'premium': 0.3
					}
				}
			]
		}
		
		flow = self.config._parse_flow('test_flow', flow_data)
		
		self.assertIsNotNone(flow, 'Flow should be created')
		self.assertFalse(flow.enabled, 'Flow should be disabled when action template is disabled')
		
	def test_flow_with_valid_templates(self):
		"""Test that flow remains enabled when all templates are valid"""
		# Create valid templates
		event_template = Mock(spec=Template)
		event_template.name = 'EventTemplate'
		event_template.is_enabled = Mock(return_value=True)
		
		action_template = Mock(spec=Template)
		action_template.name = 'ActionTemplate'
		action_template.is_enabled = Mock(return_value=True)
		
		self.config._templates = [event_template, action_template]
		
		# Parse a flow with valid templates
		flow_data = {
			'name': 'Test Flow',
			'enabled': True,
			'event': {
				'type': 'take_profit_hit',
				'template': 'EventTemplate'
			},
			'actions': [
				{
					'process_template': {
						'template': 'ActionTemplate',
						'amount': 3,
						'premium': 0.8
					}
				}
			]
		}
		
		flow = self.config._parse_flow('test_flow', flow_data)
		
		self.assertIsNotNone(flow, 'Flow should be created')
		self.assertTrue(flow.enabled, 'Flow should remain enabled when all templates are valid')


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