# Path: pyDEA/core/utils/model_builder.py
# def build_models(params, model_input):
#     ''' Creates several models and parameters in the case when
#         RETURN_TO_SCALE or ORIENTATION is set to both. If neither
#         RETURN_TO_SCALE
#         nor ORIENTATION is set to both, then no new models will be created,
#         a copy of the given model and parameters will be returned.
# 
#         Args:
#             params (Parameters): parameters.
#             model_input (InputData): data instance.
# 
#         Returns:
#             tuple of list of ModelBase, list of Parameters: tuple with two
#                 lists. The first list contains all created models, the
#                 second list contains corresponding parameters.
#     '''
#     model_factory.add_input_and_output_categories(params, model_input)
#     rts_type = params.get_parameter_value('RETURN_TO_SCALE')
#     list_of_param_objects = []
#     original_params = Parameters()
#     original_params.copy_all_params(params)
#     list_of_param_objects.append(original_params)
#     if rts_type == 'both':
#         original_params.update_parameter('RETURN_TO_SCALE', 'VRS')
#         params_with_crs = Parameters()
#         params_with_crs.copy_all_params(original_params)
#         params_with_crs.update_parameter('RETURN_TO_SCALE', 'CRS')
#         list_of_param_objects.append(params_with_crs)
#     orientation_type = original_params.get_parameter_value('ORIENTATION')
#     nb_param_objs = len(list_of_param_objects)
#     if orientation_type == 'both':
#         possible_orientation = ['input', 'output']
#         for count in range(nb_param_objs):
#             assert(count < 2)
#             param_obj = list_of_param_objects[count]
#             param_obj.update_parameter('ORIENTATION',
#                                        possible_orientation[count])
#             new_param_obj = Parameters()
#             new_param_obj.copy_all_params(param_obj)
#             new_param_obj.update_parameter('ORIENTATION',
#                                            possible_orientation[1 - count])
#             list_of_param_objects.append(new_param_obj)
# 
#     models = []
#     for param_object in list_of_param_objects:
#         models.append(model_factory.create_model(param_object, model_input))
#     return models, list_of_param_objects
# 
# Path: pyDEA/core/data_processing/parameters.py
# def parse_parameters_from_file(filename):
#     ''' Reads parameters from a given file. If file does not exist, the
#         exception will be thrown. Returns Parameters object with
#         all parameters. Does not validate parameters.
#         Throws an exception if there are repeating
#         parameters (all parameters must be unique).
#         All parameters must follow convention: <param_name> {param_value}.
#         Supports one line comments:
#         <param_name> {param_value} # this parameter is important.
#         If some parameters are missing, their value will be set to empty
#         string.
# 
#         Args:
#             filename (str): path to file with parameters. Only text files
#                 are accepted, but actual file extension does not matter.
# 
#         Returns:
#             Parameters: parameter object with parsed parameters.
# 
#         Raises:
#             FileNotFound: if given file does not exist.
#             ValueError: if file does not contain any valid parameters.
#     '''
#     pattern = ''.join(['<(', VALID_PARAM_NAME, r')>\s*{(',
#                        VALID_PARAM_VALUE, ')}'])
#     params = Parameters()
#     # will raise IOError exception if fileName
#     # does not exists, 'rU' - r - read mode,
#     # U - Universal for encoding
#     nb_parsed_params = 0
#     with open(filename, 'rU') as file_with_params:
#         for line in file_with_params:
#             line = extract_comment(line)
#             matched_params = re.findall(pattern, line)
#             for match in matched_params:
#                 if match[0] in VALID_PARAM_NAMES:
#                     params.update_parameter(match[0], match[1])
#                     nb_parsed_params += 1
#     if nb_parsed_params == 0:
#         raise ValueError('File {filename} does not contain any valid'
#                          ' parameter values'.format(filename=filename))
#     return params


from pyDEA.core.utils.model_builder import build_models
from pyDEA.core.data_processing.parameters import parse_parameters_from_file
from pyDEA.core.data_processing.read_data_from_xls import construct_input_data_instance
from pyDEA.core.data_processing.read_data_from_xls import read_data, convert_to_dictionary


def _construct_params_and_input():
    filename = 'tests/params_new_format.txt'
    params = parse_parameters_from_file(filename)
    categories, data, dmu_name, sheet_name = read_data(
        params.get_parameter_value('DATA_FILE'))
    coefficients, has_same_dmus = convert_to_dictionary(data)
    model_input = construct_input_data_instance(categories, coefficients)
    return params, model_input


def _check_params_are_the_same(params_to_check, params, except_params):
    for key, value in params.params.items():
        if key not in except_params:
            assert value == params_to_check.params[key]


def test_build_models_one_model():
    params, model_input = _construct_params_and_input()

# Path: pyDEA/core/utils/model_builder.py
# def build_models(params, model_input):
#     ''' Creates several models and parameters in the case when
#         RETURN_TO_SCALE or ORIENTATION is set to both. If neither
#         RETURN_TO_SCALE
#         nor ORIENTATION is set to both, then no new models will be created,
#         a copy of the given model and parameters will be returned.
# 
#         Args:
#             params (Parameters): parameters.
#             model_input (InputData): data instance.
# 
#         Returns:
#             tuple of list of ModelBase, list of Parameters: tuple with two
#                 lists. The first list contains all created models, the
#                 second list contains corresponding parameters.
#     '''
#     model_factory.add_input_and_output_categories(params, model_input)
#     rts_type = params.get_parameter_value('RETURN_TO_SCALE')
#     list_of_param_objects = []
#     original_params = Parameters()
#     original_params.copy_all_params(params)
#     list_of_param_objects.append(original_params)
#     if rts_type == 'both':
#         original_params.update_parameter('RETURN_TO_SCALE', 'VRS')
#         params_with_crs = Parameters()
#         params_with_crs.copy_all_params(original_params)
#         params_with_crs.update_parameter('RETURN_TO_SCALE', 'CRS')
#         list_of_param_objects.append(params_with_crs)
#     orientation_type = original_params.get_parameter_value('ORIENTATION')
#     nb_param_objs = len(list_of_param_objects)
#     if orientation_type == 'both':
#         possible_orientation = ['input', 'output']
#         for count in range(nb_param_objs):
#             assert(count < 2)
#             param_obj = list_of_param_objects[count]
#             param_obj.update_parameter('ORIENTATION',
#                                        possible_orientation[count])
#             new_param_obj = Parameters()
#             new_param_obj.copy_all_params(param_obj)
#             new_param_obj.update_parameter('ORIENTATION',
#                                            possible_orientation[1 - count])
#             list_of_param_objects.append(new_param_obj)
# 
#     models = []
#     for param_object in list_of_param_objects:
#         models.append(model_factory.create_model(param_object, model_input))
#     return models, list_of_param_objects
# 
# Path: pyDEA/core/data_processing/parameters.py
# def parse_parameters_from_file(filename):
#     ''' Reads parameters from a given file. If file does not exist, the
#         exception will be thrown. Returns Parameters object with
#         all parameters. Does not validate parameters.
#         Throws an exception if there are repeating
#         parameters (all parameters must be unique).
#         All parameters must follow convention: <param_name> {param_value}.
#         Supports one line comments:
#         <param_name> {param_value} # this parameter is important.
#         If some parameters are missing, their value will be set to empty
#         string.
# 
#         Args:
#             filename (str): path to file with parameters. Only text files
#                 are accepted, but actual file extension does not matter.
# 
#         Returns:
#             Parameters: parameter object with parsed parameters.
# 
#         Raises:
#             FileNotFound: if given file does not exist.
#             ValueError: if file does not contain any valid parameters.
#     '''
#     pattern = ''.join(['<(', VALID_PARAM_NAME, r')>\s*{(',
#                        VALID_PARAM_VALUE, ')}'])
#     params = Parameters()
#     # will raise IOError exception if fileName
#     # does not exists, 'rU' - r - read mode,
#     # U - Universal for encoding
#     nb_parsed_params = 0
#     with open(filename, 'rU') as file_with_params:
#         for line in file_with_params:
#             line = extract_comment(line)
#             matched_params = re.findall(pattern, line)
#             for match in matched_params:
#                 if match[0] in VALID_PARAM_NAMES:
#                     params.update_parameter(match[0], match[1])
#                     nb_parsed_params += 1
#     if nb_parsed_params == 0:
#         raise ValueError('File {filename} does not contain any valid'
#                          ' parameter values'.format(filename=filename))
#     return params


# Path: tests/test_model_builder.py
from pyDEA.core.utils.model_builder import build_models
from pyDEA.core.data_processing.parameters import parse_parameters_from_file
from pyDEA.core.data_processing.read_data_from_xls import construct_input_data_instance
from pyDEA.core.data_processing.read_data_from_xls import read_data, convert_to_dictionary



def _construct_params_and_input():
    filename = 'tests/params_new_format.txt'
    params = parse_parameters_from_file(filename)
    categories, data, dmu_name, sheet_name = read_data(
        params.get_parameter_value('DATA_FILE'))
    coefficients, has_same_dmus = convert_to_dictionary(data)
    model_input = construct_input_data_instance(categories, coefficients)
    return params, model_input


def _check_params_are_the_same(params_to_check, params, except_params):
    for key, value in params.params.items():
        if key not in except_params:
            assert value == params_to_check.params[key]


def test_build_models_one_model():
    params, model_input = _construct_params_and_input()

    models, all_params = build_models(params, model_input)