import glob
import os.path
import numpy as np
from ase import Atom, Atoms
#------------------------------------------------------------------------------------------
eVtokcalpermol = 23.060548012069496
#------------------------------------------------------------------------------------------
def get_normaltermination_mopac(filename):
    if not os.path.isfile(filename):
        return -1
    abnormal = 0
    with open(filename, 'r') as f:
        for line in f:
            if "Error and normal termination messages reported" in line:
                abnormal += 1
    return 1 if abnormal == 0 else 0
#------------------------------------------------------------------------------------------
def get_energy_mopac(filename):
    ene_eV = None
    with open(filename, 'r') as f:
        for line in f:
            if "TOTAL ENERGY" in line:
                try:
                    ene_eV = float(line.split()[3])
                except (IndexError, ValueError):
                    continue
    if ene_eV is None:
        return None
    return ene_eV * eVtokcalpermol
#------------------------------------------------------------------------------------------
def get_cell_mopac(filename):
    """Return 3x3 cell matrix if present, otherwise None"""
    with open(filename, 'r') as f:
        for line in f:
            if '      Tv         ' in line:
                a = []
                for _ in range(3):
                    ls = next(f).split()
                    if len(ls) < 6:
                        a.append([float(ls[2]), float(ls[3]), float(ls[4])])
                    else:
                        a.append([float(ls[2]), float(ls[4]), float(ls[6])])
                return np.array(a)
    return None
#------------------------------------------------------------------------------------------
def get_geometry_mopac(pathfilename):
    nt = get_normaltermination_mopac(pathfilename)
    if nt == -1:
        return False
    energy = get_energy_mopac(pathfilename)
    if energy is None:
        return False
    namein = os.path.basename(pathfilename).split('.')[0]
    cell = get_cell_mopac(pathfilename)
    atoms = Atoms()
    atoms.info['c'] = nt
    atoms.info['e'] = energy
    atoms.info['i'] = namein
    if cell is not None:
        atoms.set_cell(cell)
        atoms.pbc = True
    with open(pathfilename, 'r') as f:
        for line in f:
            if '                             CARTESIAN COORDINATES' in line:
                for ii in range(2): line=f.readline()
                ls = line.split()
                while ( ls != [] ):
                    symbol=str(ls[1])
                    x, y, z=float(ls[2]), float(ls[3]), float(ls[4])
                    atoms.append(Atom(symbol=symbol, position=(x, y, z)))
                    line=f.readline()
                    ls = line.split()
    return atoms
#------------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------------
def xyzs_from_outputs_mopac():
    molecules = []
    for outfile in sorted(glob.glob("*.out")):
        mol = get_geometry_mopac(outfile)
        if mol is not False:
            molecules.append(mol)
        else:
            print(f"Skipped {outfile}")
    return molecules
#------------------------------------------------------------------------------------------
def get_freqneg_mopac(filename):
    freq_negative = 0
    with open(filename, 'r') as f:
        for line in f:
            if "FREQ." in line:
                freq = float(line.split()[1])
                if freq < 0.0:
                    freq_negative += 1
    return freq_negative
#------------------------------------------------------------------------------------------
def cutter_negfreq_mopac(moleculein, path):
    moleculeout = []
    for mol in moleculein:
        basename = mol.info['i']
        freqneg = get_freqneg_mopac(os.path.join(path, basename + '.out'))
        if freqneg == 0:
            moleculeout.append(mol)
        else:
            print(f"{basename} ... DISCARDED (negative frequency)")
    return moleculeout
#------------------------------------------------------------------------------------------
def example()
    from aegon.libutils import writexyzs
    filename='pit.out'
    nt=get_normaltermination_mopac(filename)
    ene=get_energy_mopac(filename)
    print("Etot = %.8f kcal/mol" %(ene))
    atom=get_geometry_mopac(filename)
    writexyzs(atom, 'final.xyz')
