#! /usr/bin/env python
###################################################################
#                mw_utils.py                                            #
#  Created : Jan 2017                                             #
#                                                                 #
#  Author:                                                        #
#     Matthieu Haefele                                            #
#     matthieu.haefele@maisondelasimulation.fr                    #
#     Maison de la Simulation USR3441                             #
#                                                                 #
#  General utility tool that manages/assits in production duties  #
###################################################################

import os
import re
import sys
import glob
import shutil

def status(run_dir):
  """Returns a string containing finished, cg_failed or unknown depending on the status of the job"""

  if not os.path.isdir(run_dir):
    return 'Not a directory'

  runtime_present = os.path.isfile(os.path.join(run_dir, 'runtime.inpt'))
  data_present = os.path.isfile(os.path.join(run_dir, 'data.inpt'))
  if not runtime_present or not data_present:
    return 'Not a Metalwalls run directory'

  fname = os.path.join(run_dir, 'run.out')
  if not os.path.isfile(fname):
    return 'Not started'
  else:
    f = open(fname, 'r')
    lines = f.readlines()
    f.close()

    if len(lines) < 150:
      return "Not finished"

    for l in list(reversed(lines))[50:150]:
      if 'Total elapsed time' in l:
        return "Finished"
    
    return "Not finished"
    
    
def extract_run_number(name):
  pattern = re.compile('^([a-zA-Z\-_]*)([0-9]*)$')
  res = pattern.search(name)
  if res != None:
    basename = res.group(1)
    num = int(res.group(2))
    return basename, num
  else:
    return None, None

def find_finished_run(runs):
  for i in reversed(runs):
    if status(i) == "Finished":
      return i
  return None

def build_run_from(finished=False):
  runs = glob.glob("run*")
  if len(runs) == 0:
    print 'Error: could not find a run directory in %s'%(str(os.path.abspath(".")))
    return None
  runs.sort()

  if finished:
    run_dir = find_finished_run(runs)
    if run_dir == None:
      print 'Error: no finshed run in existing run dirs'
      return None
  else:  
    run_dir = runs[-1]

  basename, num = extract_run_number(run_dir)
  if basename != None:
    return basename+'%03d'%(num)
  else:
    print 'Error: directory name could not be generated from existing run dirs'
    return None

def build_run_to(run_from):
  path,dir_name = os.path.split(os.path.abspath(run_from))
  basename, num = extract_run_number(dir_name)
  if basename != None:
    return os.path.join(path, basename+'%03d'%(num+1))
  else:
    print 'Error: new directory name could not be generated from directory name %s'%dir_name
    return None


def find_restart(run_from):
  res = glob.glob(os.path.join(run_from,"restart.*.out"))
  if len(res) == 0:
    print 'Error: could not find a restart file in %s'%(str(run_from))
    return None
  res.sort()
  return res[-1] 

def restart(run_from, run_to):
  """Build a directory run_dest with everything ready to continue the simulation that stopped in run_from"""

  if run_from == None:
    run_from = build_run_from()

  if run_to == None:
    run_to = build_run_to(run_from)

  restart = find_restart(run_from)

  if run_to == None or restart == None:
    return None

  os.makedirs(run_to)
  shutil.copy(restart, os.path.join(run_to, "data.inpt"))
  shutil.copy(os.path.join(run_from, "runtime.inpt"), run_to)
  matrix_file = os.path.join(run_from, "matrix.inpt")
  if os.path.isfile(matrix_file):
    shutil.copy(matrix_file, run_to)

  return run_to

def equil(run_from, run_to):
  """Copy in run_dest everything necessary except the runtime.inpt to continue the simulation that stopped in run_from"""

  if run_from == None:
    run_from = build_run_from(finished=True)

  if run_to == None:
    run_to = build_run_to(run_from)

  restart = find_restart(run_from)

  if run_to == None or restart == None:
    return None

  shutil.copy(restart, os.path.join(run_to, "data.inpt"))
  matrix_file = os.path.join(run_from, "matrix.inpt")
  if os.path.isfile(matrix_file):
    shutil.copy(matrix_file, run_to)

  return run_to
    
    
    
def ls(run_from, run_to):
  """Build a directory run_dest with everything ready to continue the simulation that stopped in run_from"""
  pass



