import globals  # our source
import re
import sys
import os, os.path


class Comparison:
	def __init__(self, l1, l2):
		self.list2_file = '' # (last if there are many) file name with goal results (if they are stored in a file)
		self.list1 = self.prepare_fill_in_files(l1)
		self.list2 = self.prepare_fill_in_files(l2)
		self.p1 = 0  # updated position within list1
		self.p2 = 0  # updated position within list2
		self.equal = True  # the final comparison result
		self.result = ""  # details of comparing individual lines

		while not self.finished():
			if not self.compare_element():
				self.equal = False

	@staticmethod
	def load_platform_specific(file_name):
		name = file_name + "-" + globals.PLATFORM + ".goal"

		try:
			fin = open(os.path.join(globals.THISDIR, name), encoding='utf8')  # first we look for the file with the specialized name (platform-dependent)...
		except IOError as e1:
			try:
				fin = open(os.path.join(globals.THISDIR, file_name + ".goal"), encoding='utf8')  # ...if there is no such file, we try to find the default file
			except IOError as e2:
				print()
				print(e1)
				print(e2)
				print('Proceeding as if the missing file were empty.')
				return []
		list_of_lines = []
		for line in fin:
			line = globals.stripEOL(line)
			list_of_lines.append(line)
		return list_of_lines

	def prepare_fill_in_files(self, list_of_lines):  # when finds a line with SPEC_USEPLATFORMDEPENDENTFILE, replaces it with the contents of the appropriate file
		new_list = []
		for l in list_of_lines:
			if l.startswith(globals.SPEC_INSERTPLATFORMDEPENDENTFILE):
				file_name = l[len(globals.SPEC_INSERTPLATFORMDEPENDENTFILE):]
				new_list += self.load_platform_specific(file_name)
				self.list2_file = file_name
			else:
				new_list.append(l)
		return new_list

	def finished(self):
		return self.p1 >= len(self.list1) and self.p2 >= len(self.list2)

	@staticmethod
	def compare_strings(s1, s2):
		if s1 == s2:
			return True
		if not globals.WIN_SLASH_SENSITIVE and os.path.sep == '\\':  # give a chance for approximate comparison - does not distinguish /\ but only on the windows platform
			return s1.replace('\\', '/') == s2  # and matches only the local output, assuming that the goal uses linux-standard /
		else:
			return False

	def compare_element(self):
		e1 = "(missing)" if self.p1 >= len(self.list1) else self.list1[self.p1]
		e2 = "(missing)" if self.p2 >= len(self.list2) else self.list2[self.p2]
		e2disp = e2
		if e2.startswith(globals.SPEC_SKIPTO):
			e2 = e2[len(globals.SPEC_SKIPTO):]
			waiting = True
			if self.p1 >= len(self.list1):  # exception: skipto becomes a standard comparison when the input stream ends (because then we know we will not read anything more than we have now)
				waiting = False
		else:
			waiting = False
		if e2.startswith(globals.SPEC_REGEXP):
			equal = re.match(e2[len(globals.SPEC_REGEXP):], e1)
		else:
			equal = self.compare_strings(e1, e2)  # ignoring the discrimination of /\ will work only when regexp's are not used
		self.result += repr(e1) + " "
		if equal:
			self.p2 += 1
		else:
			if waiting:  # handling skipto:
				if self.p1 >= len(self.list1):
					self.p2 += 1
				else:
					equal = True
			else:
				self.p2 += 1
		if equal:
			self.result += globals.ANSI_SETGREEN + "ok" + globals.ANSI_RESET + "\n"  # if both are identical, we display only the left one
		else:
			self.result += globals.ANSI_SETRED + "<FAIL>" + globals.ANSI_RESET + " "
			self.result += repr(e2disp) + "\n"
		self.p1 += 1
		return equal
