package org.subalternproductions.seepResource.dsl.parser.validation
{
	import org.subalternproductions.seepResource.dsl.parser.IPResult;
	import org.subalternproductions.seepResource.dsl.parser.PObjectMap;
	import org.subalternproductions.seepResource.dsl.parser.PValidationError;
	import org.subalternproductions.util.assert.Assert;

	public class ObjectValidationCP
	{
		public function ObjectValidationCP()
		{
		}
		
		
		public var label:String;
		public var input:Object;
		

		public var out:Object;
		public var directives:Array; 
		
		private var cmp:ObjectValidator = new ObjectValidator;
		

		public var ok:Boolean = false;
		
		public function execute(sscope:*/*SeasScope*/):Boolean {
			Assert.fail('deprecated')
			var map:PObjectMap = sscope.map;
			
			var inputResult:IPResult = map.toResult(input);
			var initialErrors:Number = sscope.map.validationErrors ? sscope.map.validationErrors.length : 0;
			
			if (out) {
				var expResult:IPResult = map.toResult(out);
				cmp.validateResult(input, out, map);
			} 
			// else - if there's no out, then we're testing parsing and basic object mapping only
		
			
			for each (var d:ASTRenderValidator in directives) {
				validateDirective(d, sscope);
			}
			
			ok = inputResult.isValid(map) 
				&& !(map.validationErrors && map.validationErrors.length > initialErrors); // need to do this while there is a possibility of errors not registered as results
		
			
			return ok;
			
		} // execute
		
	
		// --- TO_EXTRACT: seperate validateion , pending developmenet of directive infrastruture 
		
		
		private function validateDirective(d:ASTRenderValidator,sscope:*/*SeasScope*/):void {
			var map:PObjectMap = sscope.map;
			if (d.name == "render") {
				Assert.fail('deprecated')
				var codegen:* // ASTCodeGen = sscope.getRenderer(d.target);
				
				if (codegen == null) {
					logErr(UNKNOWN_TARGET, map.toResult(d), map, "unknow target " + d.target);
				}
				
			
				var out:String = codegen.compile(input, sscope);
				var split:Array = out.split("\n");
				if (split.length > 0) {
					//  TODO - create result for mapping   
					
					for (var i:Number = 0; i < split.length; i++) {
						if (i >= d.rawContent.length ) {
							var result:IPResult = map.toResult(d);
							logErr(TOO_FEW_LINES, result, map, "actual result is longer that tested for");
							break;
						}
						var found:String = split[i];
						var expected:String = d.rawContent[i]

						if (found != expected) {
							var lineResult:IPResult = map.toResult(d.rawContent, null, i);
							logErr(MISMATCH, lineResult, map,
									"mismatched line :" +  // todo - add line number   
									"\n expected: \"" + expected + "\" " +
								 	"\n found:    \""  + found+ "\"");
						}
					}
					
				} else if (d.rawContent && d.rawContent.length > 0) {
					Assert.fail(); // TODO - add an error for 0 length content
				}
				
			} else {
				Assert.fail(' unknown directive ')
			}

		}
		
		// TO_EXTRACT
		private function logErr(type:String, result:IPResult, map:PObjectMap, msg:String = ""):void {
			Assert.assert(result != null);
			var err:PValidationError = new PValidationError(RENDER_VALIDATION, result, msg, type);
			map.logValidationError(err)

		}
		
		public static const RENDER_VALIDATION:String = "validate_rendering";
							
		public static const MISMATCH:String = "mismatch"
		public static const TOO_FEW_LINES:String = "tooFewLines";
		public static const UNKNOWN_TARGET:String = "unknownTarget"
		
		public static const BAD_PROPERTY:String = "badProperty";
			
	} // class
} // package