import numpy as np
import re

from .Core import Experiment


def _parse_info(info):
    result = {}

    item = info.strip().split('=')
    if len(item) < 2:
        return result

    info = item[0].strip()
    value = item[1].strip() if len(item) == 2 else '='.join(item[1:]).strip()

    if info == 'PEPMASS':
        try:
            result = dict(precursor_mz=float(value))
        except ValueError:
            result = dict(precursor_mz=float(value.split()[0]))


    elif info == 'CHARGE':
        _charge_dict = {'-': -1, '+': 1}
        if value[-1] in _charge_dict:
            charge = _charge_dict[value[-1]] * int(value[:-1])
        elif value[0] in _charge_dict:
            charge = _charge_dict[value[0]] * int(value[1:])
        else:
            charge = int(value)
        result = dict(charge=charge)
    else:
        result = {info.lower(): value}

    return result


def read(filename_input):
    experiment = Experiment.Experiment()
    scan_no = 0

    with open(filename_input) as fi:
        is_spectra_started = False
        for line in fi:
            line = line.strip()
            if len(line) == 0 or line[0] == '#':
                continue

            if line.find('BEGIN ION') >= 0:
                is_spectra_started = True
                scan_no += 1
                spectrum = dict(
                    charge=1,
                    precursor_mz=0.,
                    spectrum=[],
                    rtinseconds=-1.
                )
                continue

            if line.find('END IONS') >= 0:
                if 'scan' not in spectrum:
                    if spectrum.get('title', '').find('scan') >= 0:
                        spectrum['scan'] = re.search("scan=(\d+)", spectrum['title']).group(1)
                    else:
                        spectrum['scan'] = scan_no

                experiment.add_ms2(spectrum_data=np.array(spectrum['spectrum'], np.float32).T,
                                   precursor_mz=spectrum['precursor_mz'],
                                   precursor_charge=spectrum['charge'],
                                   scan_num=spectrum['scan'],
                                   retention_time=spectrum['rtinseconds'])
                continue

            if not is_spectra_started:
                # info.update(_parse_info(line))
                continue

            if line.find('=') >= 0:
                spectrum.update(_parse_info(line))
            else:
                items = line.split()
                assert len(items) == 2, "Error found when parse {}".format(line)
                spectrum['spectrum'].append((float(items[0]), float(items[1])))

        return experiment
