# -*- coding: utf-8 -*-
from __future__ import print_function

import sys, base64, json, os, inspect, imp, shutil, tempfile

DEBUG = True;

def log(s):
    if DEBUG:
        print(s)

compiler_option_file_options = [
  "@", # GNU
  "-@", "-@@", "--via", "--option-file=", "--cmd-file=", "-f",
  "-subcommand=", "-su=" # Renesas
]

def find_file(path, proj_dir):
  result = path
  proj = os.path.join(proj_dir, "project.txt")
  if not os.path.exists(result) and os.path.exists(proj):
    pf = open(proj)
    for p in pf:
      p = p.strip()
      while os.path.exists(p) and not os.path.exists(result):
        result = os.path.join(p, path)
        p = os.path.dirname(p)
  if not os.path.exists(result):
    result = None
  return result

def copy_tmp(o, path, proj_dir, copied_args):
  p = find_file(path, proj_dir)
  if p:
    (tmpf, tmpp) = tempfile.mkstemp(dir=proj_dir, suffix=".tmp")
    os.close(tmpf)
    shutil.copyfile(p, tmpp)
    copied_args.append(o + tmpp)
  else:
    copied_args.append(o + path)

def extract_flags(myCct, compile_args, define_flag, include_flag, options_flag, source_extensions):
    proj_dir = os.path.dirname(os.path.dirname(os.path.dirname(
      os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(
      os.path.dirname(myCct.filePath()))))))))
    f = open(os.path.join(proj_dir, "build_commands.txt"), "a")
    # leave file to guess CWD for relative paths later and ignore command
    if os.path.basename(compile_args[0] ).lower().startswith("uv"):
      for opt in compile_args:
        if opt.lower().endswith("uvproj") and os.path.exists(opt):
          pf = open(os.path.join(proj_dir, "project.txt"), "w")
          print(opt, file=pf)
          pf.close()
    else:
      copied_args = [ ]
      next_is_path = False
      for opt in compile_args:
        if next_is_path:
          next_is_path = False
          copy_tmp("", opt, proj_dir, copied_args)
        else:
          copied = False
          for o in compiler_option_file_options:
            if not copied:
              if o == opt:
                next_is_path = True
                copied = True
                copied_args.append(opt)
              elif opt.startswith(o):
                copied = True
                copy_tmp(o, opt[len(o):], proj_dir, copied_args)
          if not copied:
            copied_args.append(opt)
      print(json.dumps(copied_args), file=f)
    f.close();

# return dummies
    msg = { }
    msg['defines'] = [ ]
    msg['includes'] = [ ]
    msg['files'] = [ ]

    myCct.exit_error(0, json.dumps(msg,ensure_ascii=False).encode('utf8'))


if __name__=="__main__":
    """
    Extract Include, Defines and (optionally) Source File(s).

    This script is called with a compile line and it will return the
    extracted Defines, Includes and optionally the source files(s).

    Currently 5 parameters are supplied:

    [1] The compile line, base64 encoded. Arguments are separated by the
    ASCII RS character (x1e).

    [2] The pipe to send data back to Framework

    [3] The Define flags, taken from Project Properties.
        Individual fields are comma separated.

    [4] The Include flags, taken from Project Properties.
        Individual fields are comma separated.

    [5] The FIRST Option file data.
        Individual fields are comma separated.

    [6] List of source file extensions.
        Individual fields are comma separated.

    If successful it should return a JSON structure with the lists;
    defines, includes and files set.

    Fatal errors should call exit_error with an error code and message.
    """

    # This relative path may need changing depending where this script lives
    qafDir = os.path.abspath(
        os.path.join(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))), "..", "..", "core_qaf"))
    if qafDir not in sys.path:
        sys.path.insert(0, qafDir)
    try:
        imp.find_module('qaf')
    except ImportError:
        print('Unable to locate "qaf" module. Exiting.', file= sys.stderr)
        sys.exit(1)
    import qaf
    myCct = qaf.Cip(os.path.abspath(inspect.getfile(inspect.currentframe())))

    if len(sys.argv) < 7:
        myCct.exit_error(1, 'Not enough parameters specified to script.')


    log("This is the name of the script: {}".format(sys.argv[0]))
    log("Number of arguments: {}".format(len(sys.argv)))
    log("The arguments are: {}". format(str(sys.argv)))
    for n in range(len(sys.argv)):
        if n != 1:
            log("[{}]".format(sys.argv[n]))
        else:
            s = base64.b64decode(sys.argv[n])
            if not isinstance(s, str):
              s = s.decode()
            compile_args = s.split('\x1e')  # RS separated
            log(compile_args)

    define_flag  = sys.argv[3].split(',')
    include_flag = sys.argv[4].split(',')
    options_flag = sys.argv[5].split(',')
    source_extensions = sys.argv[6].split(',')

    extract_flags(myCct, compile_args, define_flag, include_flag, options_flag, source_extensions)
