#   pyRCV2: Preferential vote counting
#   Copyright © 2020–2021  Lee Yingtong Li (RunasSudo)
#
#   This program is free software: you can redistribute it and/or modify
#   it under the terms of the GNU Affero General Public License as published by
#   the Free Software Foundation, either version 3 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU Affero General Public License for more details.
#
#   You should have received a copy of the GNU Affero General Public License
#   along with this program.  If not, see <https://www.gnu.org/licenses/>.

from pyRCV2.model import Constraint

def CONException(Exception):
	pass

def readCON(data, election):
	lines = data.split('\n')
	
	constraints = {}
	
	for line in lines:
		if not line:
			continue
		
		bits = line.split(' ')
		
		# Read constraint category
		if bits[0].startswith('"'):
			idx = next(i for i in range(len(bits)) if bits[i].endswith('"'))
			category = ' '.join(bits[0:idx+1]).strip('"')
		else:
			idx = 0
			category = bits[0]
		
		# Read constraint name
		idx += 1
		if bits[idx].startswith('"'):
			idx2 = next(i for i in range(idx, len(bits)) if bits[i].endswith('"'))
			name = ' '.join(bits[idx:idx2+1]).strip('"')
			idx = idx2
		else:
			name = bits[idx]
		
		# Read min, max
		n_min = int(bits[idx + 1])
		n_max = int(bits[idx + 2])
		
		# Read candidates
		candidates = []
		for v in bits[idx+3:]:
			candidates.append(election.candidates[int(v)-1])
		
		if category not in constraints:
			constraints[category] = {}
		
		if name in constraints[category]:
			raise CONException('Duplicate constraint "' + name + '" in category "' + category + '"')
		
		constraints[category][name] = Constraint(category, name, n_min, n_max, candidates)
	
	return constraints
