#  Copyright (C) 2017 The authors of Py-ChemShell
#
#  This file is part of Py-ChemShell.
#
#  Py-ChemShell is free software: you can redistribute it and/or modify
#  it under the terms of the GNU Lesser General Public License as
#  published by the Free Software Foundation, either version 3 of the
#  License, or (at your option) any later version.
#
#  Py-ChemShell 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 Lesser General Public License for more details.
#
#  You should have received a copy of the GNU Lesser General Public
#  License along with Py-ChemShell.  If not, see
#  <http://www.gnu.org/licenses/>.

import chemsh
from ...dl_py2f import utils

# notes:
#     _regex[key] = [ row_0, # starting row
#                     row_n, # ending row
#                     row_i, # row increment
#                     col_0, # starting col
#                     col_n, # ending col
#                     col_i, # col increment
#                     skip , # skip the first (skip-1) match(es),
#                     coeff, # unit conversion coefficient
#                   ]
def parse(filename, _regex=None, receiver=None, number_only=True, prefix='', **kwargs):
    '''Parse output file'''

    from re import search as re_search
    from os import path

    # YL 13/08/2022: path prefix
    filename = path.join(prefix, filename)

    with open(filename, 'r') as fp:

        # counter: how many matches
        counter = 0
        lbuff = []

        # loop over lines
        for line in fp:

            # loop over keywords to search (YL: normally should contain only one key)
            for key in _regex.keys():

                # if matched
                if re_search(key, line) != None:

                    if chemsh.CHEMSH_DEBUG > 4:
                        print(" >>> files.out.parse(): line matching keyword \"{}\":\n {}".format(key, line))

                    counter += 1

                    # ignore the first (skip-1) matches
                    if counter < _regex[key][6]:
                        continue

                    # skip line(s) otherwise
                    for i in range(_regex[key][0]):
                        line = next(fp)

                    # 1st row
                    # YL 30/09/2020: this was for backward compatibility to get numbers-only result
                    try:
                        if number_only:
                            lbuff.extend(list(utils.strutils.str2num(line.split()[j])*_regex[key][7]
                                                               for j in range(_regex[key][3],
                                                                              _regex[key][4]+1,
                                                                              _regex[key][5])))
                        # YL 30/09/2020: new universal container to get mixed result
                        else:
                            lbuff.extend(line.split()[j]
                                         for j in range(_regex[key][3],
                                                        _regex[key][4]+1,
                                                        _regex[key][5]))
                    # YL 27/03/2021: the above may fail in some cases where no appropriate keyword is possible (e.g., "ENERGY:" in NAMD)
                    except:
                        continue

                    # 2nd to the last row
                    for i in range(_regex[key][1]-_regex[key][0]):
                        line = next(fp)
                        try:
                            # YL 30/09/2020: this was for backward compatibility to get numbers-only result
                            if number_only:
                                lbuff.extend(list(utils.strutils.str2num(line.split()[j])*_regex[key][7]
                                                                   for j in range(_regex[key][3],
                                                                                  _regex[key][4]+1,
                                                                                  _regex[key][5])))
                            # YL 30/09/2020: new universal container to get mixed result
                            else:
                                lbuff.extend(line.split()[j]
                                             for j in range(_regex[key][3],
                                                            _regex[key][4]+1,
                                                        _regex[key][5]))
                        # YL 27/03/2021: the above may fail in some cases where no appropriate keyword is possible (e.g., "ENERGY:" in NAMD)
                        except:
                            continue

        if chemsh.CHEMSH_DEBUG > 4:
            print("\n >>> files.out.parse(): lbuff =", lbuff)

        # convert to nparray
        try:
            try:
                utils.nputils.setField(receiver, lbuff, debug=chemsh.CHEMSH_DEBUG)
            # need to resize first
            except:
                receiver.resize(len(lbuff), refcheck=False)
                utils.nputils.setField(receiver, lbuff, debug=chemsh.CHEMSH_DEBUG)
            # YL 30/09/2020: also return the array for consistency
            return receiver

        # YL 30/09/2020: return lbuff if cannot convert to nparray
        except:
            return lbuff
            


