#!/usr/bin/python3
ver="2025.03.31"
############################################################
# EXTMUL Ver.2025.03.31
# (Utility to extract a dataset from multiple reaction formalism)
#
# Naohiko Otuka (IAEA Nuclear Data Section)
############################################################
import datetime
import os
import re
import argparse
import glob

import x4_x4toj4
import x4_poipoi
import x4_j4tox4

def main(file_inp,file_dict,data_id,file_out,force0):

  force=force0
# data_id  = "all"  # extract all data sets in multiple reaction formalism
  chkrid   = False  # record identificaiton not checked in X4TOJ4
  key_keep = "all"  # keep all keywords in X4TOJ4 and POIPOI
  add19    = True   # add '19' to two-digit year
  keepflg  = False  # ignore flags at col.80 in X4TOJ4
  outstr   = True   # print real numbers as strings in X4TOJ4
  delpoin  = True   # delete pointer in the output in POIPOI
  keep001  = True   # keep common subentry in POIPOI


# Conversion to J4 format by X4TOJ4
  file_js0 = "exfor0.json"
  x4_x4toj4.main(file_inp,file_dict,file_js0,key_keep,force,chkrid,add19,keepflg,outstr)

# Conversion to J4 format without pointer structure by POIPOI
  if data_id=="all":
    time=datetime.datetime.now()
    dir_js1 = time.strftime('%Y%m%d%H%M%S%f')
    os.mkdir(dir_js1)
    x4_poipoi.main(file_js0,file_dict,data_id,dir_js1,key_keep,force,delpoin,keep001)
  else:
    file_js1 = "exfor1.json"
    x4_poipoi.main(file_js0,file_dict,data_id,file_js1,key_keep,force,delpoin,keep001)

# Conversion to X4 format by J4TOX4
  if data_id=="all":
    file_js1s=glob.glob("./"+dir_js1+"/*.json")
    for file_js1 in file_js1s:
      file_exf=re.sub('json$', 'txt',file_js1)
      x4_j4tox4.main(file_js1,file_dict,file_exf,force)
  else:
    x4_j4tox4.main(file_js1,file_dict,file_out,force)

# Merging of J4TOX4 output
  if data_id=="all":
    f=open(file_out,"w")
    file_x4s=glob.glob("./"+dir_js1+"/*.txt")
    nsub=len(file_x4s)
    for isub, file_x4 in enumerate(file_x4s):
      lines=get_file_lines(file_x4)
      san=0
      for line in lines:
        if line[0:8]=="ENDENTRY":
          if isub==nsub-1:
            f.write(line)
        else:
          if line[0:6]=="SUBENT":
            san+=1
          if isub==0 or san==2:
            f.write(line)
    f.close()

  os.remove("exfor0.json")
  if data_id=="all":
    files=glob.glob("./"+dir_js1+"/*")
    for file in files:
      os.remove(file)
    os.rmdir(dir_js1)
  else:
    os.remove(file_js1)

  print("EXTMUL: Processing terminated normally.")


def get_file_lines(file):
  if os.path.exists(file):
    f=open(file, "r")
    lines=f.readlines()
    f.close()
  else:
    msg="File "+file+" does not exist."
    print_error_fatal(msg)
  return lines


def get_args(ver):

  parser=argparse.ArgumentParser(\
   usage="Extract a dataset from multiple reaction formalism",\
   epilog="example: x4_extmul.py -i exfor.txt -d dict_9131.json -e 23756.002.3 -o exfor_out.txt")
  parser.add_argument("-v", "--version",\
   action="version", version=ver)
  parser.add_argument("-i", "--file_inp",\
   help="input EXFOR file")
  parser.add_argument("-d", "--file_dict",\
   help="input JSON dictionary")
  parser.add_argument("-e", "--data_id",\
   help="EXFOR dataset ID for extraction, ('all' to process all datasets)")
  parser.add_argument("-o", "--file_out",\
   help="output EXFOR file")
  parser.add_argument("-f", "--force",\
   help="never prompt", action="store_true")

  args=parser.parse_args()
  return args


def get_input(args):
  time=datetime.datetime.now()
  date=time.strftime("%Y-%m-%d")
  print("EXTMUL (Ver."+ver+") run on "+date)
  print("-----------------------------------------")

  force0=args.force

  file_inp=args.file_inp
  if file_inp is None:
    file_inp=input("input EXFOR file [exfor.txt] ------------------> ")
    if file_inp=="":
      file_inp="exfor.txt"
  if not os.path.exists(file_inp):
    print(" ** File "+file_inp+" does not exist.")
  while not os.path.exists(file_inp):
    file_inp=input("input EXFOR file [exfor.txt] ------------------> ")
    if file_inp=="":
      file_inp="exfor.txt"
    if not os.path.exists(file_inp):
      print(" ** File "+file_inp+" does not exist.")

  file_dict=args.file_dict
  if file_dict is None:
    file_dict=input("input JSON Dictionary [dict_9131.json] --------> ")
    if file_dict=="":
      file_dict="dict_9131.json"
  if not os.path.exists(file_dict):
    print(" ** File "+file_dict+" does not exist.")
  while not os.path.exists(file_dict):
    file_dict=input("input JSON Dictionary [dict_9131.json] --------> ")
    if file_dict=="":
      file_dict="dict_9131.json"
    if not os.path.exists(file_dict):
      print(" ** File "+file_dict+" does not exist.")

  data_id=args.data_id
  if data_id is None:
    data_id=input("EXFOR dataset ID for extraction [23756.002.3] -> ")
    if data_id=="":
      data_id="23756.002.3"
  if data_id!="all":
    data_id=data_id.upper()
  if not re.compile("^[1-9A-Z]\d{4}\.\d{3}(\.[1-9A-Z])?$").search(data_id) and data_id!="all":
    print(" ** EXFOR dataset ID "+data_id+" is illegal.")
  while not re.compile("^[1-9A-Z]\d{4}\.\d{3}(\.[1-9A-Z])?$").search(data_id) and data_id!="all":
    data_id=input("EXFOR dataset ID for extraction [23756.002.3] -> ")
    if data_id!="all":
      data_id=data_id.upper()
    if data_id=="":
      data_id="23756.002.3"
    if not re.compile("^[1-9A-Z]\d{4}\.\d{3}(\.[1-9A-Z])?$").search(data_id) and data_id!="all":
      print(" ** EXFOR dataset ID "+data_id+" is illegal.")

  file_out=args.file_out
  if file_out is None:
    file_out=input("output EXFOR file [exfor_out.txt] -------------> ")
  if file_out=="":
    file_out="exfor_out.txt"
  if os.path.isfile(file_out):
    msg="File '"+file_out+"' exists and must be overwritten."
    print_error(msg,"",force0)

  return file_inp,file_dict,data_id,file_out,force0


def print_error(msg,line,force):
  print("** "+msg)
  print(line)

  if force:
    answer="Y"
  else:
    answer=""

  while answer!="Y" and answer!="N":
    answer=input("Continue? [Y] --> ")
    if answer=="":
        answer="Y"
    if answer!="Y" and answer!="N":
      print(" ** Answer must be Y (Yes) or N (No).")
  if answer=="N":
    print("program terminated")
    exit()


if __name__ == "__main__":
  args=get_args(ver)
  (file_inp,file_dict,data_id,file_out,force0)=get_input(args)
  main(file_inp,file_dict,data_id,file_out,force0)
  exit()
