# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import argparse
import os
import subprocess
import sys

def main():
  args = parseInput()

  assert validateHeaderInput(args.header), \
         "Error: '%s' is not a valid .h file" % args.header
  assert validateCodeInput(args.cc), \
         "Error: '%s' is not a valid .cc file" % args.cc
  assert validatePathInput(args.gen_dir), \
         "Error: '%s' is not a valid output directory" % args.gen_dir
  assert validateCddlInput(args.file), \
         "Error: '%s' is not a valid CDDL file" % args.file

  if args.log:
    logPath = os.path.join(args.gen_dir, args.log)
    log = open(logPath, "w")
    log.write("OUTPUT FOR CDDL CODE GENERATION TOOL:\n\n")
    log = open(logPath, "a")

    if (args.verbose):
      print("Logging to %s" % logPath)
  else:
    log = None

  if (args.verbose):
    print('Creating C++ files from provided CDDL file...')
  echoAndRunCommand([args.cddl, "--header", args.header, "--cc", args.cc,
                     "--gen-dir", args.gen_dir, args.file],
                     False, log, args.verbose)

  clangFormatLocation = findClangFormat()
  if not clangFormatLocation:
    if args.verbose:
      print("WARNING: clang-format could not be found")
    return

  for filename in [args.header, args.cc]:
    echoAndRunCommand([clangFormatLocation + 'clang-format', "-i",
                       os.path.join(args.gen_dir, filename)],
                       True, verbose=args.verbose)

def parseInput():
  parser = argparse.ArgumentParser()
  parser.add_argument("--cddl", help="path to the cddl executable to use")
  parser.add_argument("--header", help="Specify the filename of the output \
     header file. This is also the name that will be used for the include \
     guard and as the include path in the source file.")
  parser.add_argument("--cc", help="Specify the filename of the output \
     source file")
  parser.add_argument("--gen-dir", help="Specify the directory prefix that \
     should be added to the output header and source file.")
  parser.add_argument("--log", help="Specify the file to which stdout should \
     be redirected.")
  parser.add_argument("--verbose", help="Specify that we should log info \
     messages to stdout")
  parser.add_argument("file", help="the input file which contains the spec")
  return parser.parse_args()

def validateHeaderInput(headerFile):
  return headerFile and headerFile.endswith('.h')

def validateCodeInput(ccFile):
  return ccFile and ccFile.endswith('.cc')

def validatePathInput(dirPath):
  return dirPath and os.path.isdir(dirPath)

def validateCddlInput(cddlFile):
  return cddlFile and os.path.isfile(cddlFile)

def echoAndRunCommand(commandArray, allowFailure,
                      logfile = None, verbose = False):
  if verbose:
    print("\tExecuting Command: '%s'" % " ".join(commandArray))

  if logfile != None:
    process = subprocess.Popen(commandArray, stdout=logfile, stderr=logfile)
    process.wait()
    logfile.flush()
  else:
    process = subprocess.Popen(commandArray)
    process.wait()

  returncode = process.returncode
  if returncode != None and returncode != 0:
    if not allowFailure:
      sys.exit("\t\tERROR: Command failed with error code: '%i'!" % returncode)
    elif verbose:
      print("\t\tWARNING: Command failed with error code: '%i'!" % returncode)

def findClangFormat():
  executable = "clang-format"

  # Try and run from the environment variable
  for directory in os.environ["PATH"].split(os.pathsep):
    fullPath = os.path.join(directory, executable)
    if os.path.isfile(fullPath):
      return ""

  # Check 2 levels up since this should be correct on the build machine
  path = "../../"
  fullPath = os.path.join(path, executable)
  if os.path.isfile(fullPath):
    return path

  return None

if __name__ == "__main__":
  main()
