#    Virtual-IPM is a software for simulating IPMs and other related devices.
#    Copyright (C) 2021  The IPMSim collaboration <https://ipmsim.gitlab.io/>
#
#    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 <http://www.gnu.org/licenses/>.

from anna import load_from_file
import argparse
import os
import pandas
from pandas import CParserError
import sys

from virtual_ipm.simulation.output import BasicRecorder, XMLProfileRecorder


parser = argparse.ArgumentParser()
parser.add_argument(
    'filename',
    help='The filename of an csv output file generated by `BasicRecorder`. The content from this'
         'file will be converted to the XML data format.'
)
parser.add_argument(
    'binsize',
    help='The bin size of the generated histograms in [mm].'
)
parser.add_argument(
    'config',
    help='Filename pointing to the original configuration from which the results where obtained.'
)
parser.add_argument(
    '--xml-file',
    help='The name of the generated XML file. If not given then the output filename is used by '
         'replacing its suffix with ".xml".'
)
parser.add_argument(
    '--histogram-range',
    help='The range of the generated histograms in [mm] (separate values with "," (comma)). If '
         'not given the the min. and max. values of the samples are used. '
         'Example (-5mm to 5mm): --histogram-range -5,5'
)
parser.add_argument(
    '--overwrite',
    action='store_true',
    help='Use this flag to overwrite an existing XML file. Otherwise the script will abort.'
)
args = parser.parse_args()


def main():
    if not args.xml_file:
        name, suffix = os.path.splitext(args.filename)
        xml_file = '{0}.{1}'.format(name, 'xml')
    else:
        xml_file = args.xml_file
    if os.path.exists(xml_file) and not args.overwrite:
        print('Output xml file "%s" already exists. Use --overwrite to replace the file.'
              % xml_file)
        sys.exit()
    print('Writing output to: ', xml_file)

    if args.histogram_range:
        x_min, x_max = args.histogram_range.split(',')
        histogram_range = (float(x_min) * 1e-3, float(x_max) * 1e-3)
    else:
        histogram_range = args.histogram_range

    try:
        df = pandas.read_csv(args.filename)
        # noinspection PyStatementEffect
        df[BasicRecorder.possible_column_names['initial x']]
        # noinspection PyStatementEffect
        df[BasicRecorder.possible_column_names['final x']]
    except CParserError as err:
        print('The given output file is invalid: %s' % str(err))
        return -1
    except KeyError as err:
        print(
            'The given output file does not contain column "%s". The output file must contain '
            'both initial and final parameters.' % str(err)
        )
        return -1

    xml_config = XMLProfileRecorder.generate_xml_config_from_samples(
        load_from_file(args.config),
        df[BasicRecorder.possible_column_names['initial x']],
        df[BasicRecorder.possible_column_names['final x']],
        float(args.binsize) * 1e-3,
        histogram_range
    )
    xml_config.dump_to_file(xml_file)
    return 0


if __name__ == '__main__':
    sys.exit(main())
