#!/usr/bin/python3
ver="2025.12.03"
############################################################
# MAKJ4L Ver.2025.12.03
# (Utility for production and update of J4 file storage)
#
# Naohiko Otuka (IAEA Nuclear Data Section)
############################################################
import argparse
import datetime
import os
import re
import shutil
import time

if os.path.isfile("x4_x4toj4.py"):
  import x4_x4toj4
else:
  from forexy import x4_x4toj4

def  main(dir_storage,file_dict,dir_j4lib,file_trans,force0):
  time_start=time.time()

  force=force0

  if file_trans is None: 
    clean(dir_j4lib)

  if file_trans is None:
    dirs=os.listdir(dir_storage)
    for dir in dirs:
      if re.compile("^[a-z0-8]$").search(dir):
        files=os.listdir(dir_storage+"/"+dir)
        files=sorted(files)
        for file in files:
          if re.compile(dir+r"\d{4}\.txt").search(file):
            file_x4=dir_storage+"/"+dir+"/"+file
            make_j4(file_x4,dir_storage,file_dict,dir_j4lib,force)
  else:
    if os.path.exists(file_trans):
      entries=get_entry_number(file_trans,dir_storage)
      for entry in entries:
        entry=entry.lower()
        area=entry[0:1].lower()
        file_x4=dir_storage+"/"+ area+"/"+entry+".txt"
        make_j4(file_x4,dir_storage,file_dict,dir_j4lib,force)

    else:
      msg="File "+file_trans+" does not exists."
      print_error_fatal(msg,"")
  

  time_end=time.time()
  time_elapsed=format(time_end-time_start, ".2f")
  print("MAKJ4L: Processing terminated normally. "+time_elapsed+" sec.\n")


def clean(dir_storage):
  files=os.listdir(dir_storage)
  for file in files:
    if os.path.isdir(dir_storage+"/"+file):
      if re.compile("^[a-z0-8]$").search(file):
        print("Directory "+dir_storage+"/"+file+" deleted")
        shutil.rmtree(dir_storage+"/"+file)


def get_entry_number(file_trans,dir_storage):
  lines=get_file_lines(file_trans)
  entries=[]
  for line in lines:
    if re.compile("^ENTRY").search(line):
      area=line[17:18].lower()
      entry=line[17:22].lower()
      altflag=line[10:11]
      file=dir_storage+"/"+area+"/"+entry+".txt"
      if altflag==" ":           # new entries
        entries.append(entry)
      elif os.path.exists(file): # retransmitted entries
        entries.append(entry)
      else:
        msg="Revised entry "+entry+" is in "+file_trans+" but "+file+" is not in the entry storage."
        print_error_fatal(msg,"")
        
  return entries


def make_j4(file_x4,dir_storage,file_dict,dir_j4lib,force):
  m=re.compile(r"([a-z0-8]\d{4,4})\.txt$").search(file_x4)
  entry=m.group(1)
  area=entry[0:1]
  dir_out=dir_j4lib+"/"+ area
  if not (os.path.isdir(dir_out)): 
    os.mkdir(dir_out)
  file_j4=dir_out+"/"+entry+".json"
  if os.path.isfile(file_j4):
    print("updating ..."+file_j4)
  else:
    print("creating ..."+file_j4)

  key_keep =["all"]
  chkrid   = False
  add19    = True
  keepflg  = False
  outstr   = False

  x4_x4toj4.main(file_x4,file_dict,file_j4,key_keep,force,chkrid,add19,keepflg,outstr)

  return


def get_args(ver):

  parser=argparse.ArgumentParser(\
          usage="Production and update of J4 file storage",\
          epilog="example: x4_makj4l.py -i entry -d dict.json -j j4")
  parser.add_argument("-v", "--version",\
         action="version", version=ver)
  parser.add_argument("-i", "--dir_storage",\
   help="input entry storage directory")
  parser.add_argument("-d", "--file_dict",\
   help="input JSON Dictionary")
  parser.add_argument("-j", "--dir_j4lib",\
   help="output J4 library storage")
  parser.add_argument("-t", "--file_trans",\
   help="input trans tape (optional)", default=None)
  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("MAKJ4L (Ver."+ver+") run on "+date)
  print("-----------------------------------------")

  force0=args.force
  file_trans=args.file_trans

  dir_storage=args.dir_storage
  if dir_storage is None:
    dir_storage=input("directory of input entry storage [entry] -> ")
    if dir_storage=="":
      dir_storage="entry"

  if not os.path.isdir(dir_storage):
    print(" ** Directory '"+dir_storage+"' does not exist.")
  while not os.path.isdir(dir_storage):
    dir_storage=input("directory of input entry storage [entry] -------> ")
    if dir_storage=="":
      dir_storage="entry"
    if not os.path.isdir(dir_storage):
      print(" ** Directory '"+dir_storage+"' does not exist.")

  file_dict=args.file_dict
  if file_dict is None:
    file_dict=input("JSON Dictionary [dict.json] --------------> ")
    if file_dict=="":
      file_dict="dict.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("JSON DIctionary [dict.json] --> ")
    if file_dict=="":
      file_dict="dict.json"
    if not os.path.exists(file_dict):
      print(" ** File "+file_dict+" does not exist.")

  dir_j4lib=args.dir_j4lib
  if dir_j4lib is None:
    dir_j4lib=input("directory of output J4 file storage [j4] -> ")
    if dir_j4lib=="":
      dir_j4lib="j4"

  if os.path.isdir(dir_j4lib):
    if file_trans is None:
      msg="Directory '"+dir_j4lib+"' exists and must be initialised."
      print_error(msg,"",force0)
  else:
    msg="Directory '"+dir_j4lib+"' does not exist and must be created."
    print_error(msg,"",force0)
    os.mkdir(dir_j4lib)

  file_trans=args.file_trans
  print("input trans tape -------------------------> "+file_trans)
  print("\n")

  return dir_storage,file_dict,dir_j4lib,file_trans,force0


def print_error_fatal(msg,line):
  print("** "+msg)
  print(line)
  exit()


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()


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


if __name__ == "__main__":
  args=get_args(ver)
  (dir_storage,file_dict,dir_j4lib,file_trans,force0)=get_input(args)
  main(dir_storage,file_dict,dir_j4lib,file_trans,force0)
  exit()
