#!/usr/bin/env python
# Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
#
# This python script creates a tar archive and a C++ source file which contains
# the tar archive as an array of bytes.

import os
import sys
from os.path import join, splitext
import time
from optparse import OptionParser
from datetime import date
import tarfile
import tempfile
import gzip

def CreateTarArchive(tar_path, client_root, compress, files):
  mode_string = 'w'
  tar = tarfile.open(tar_path, mode=mode_string)
  for input_file_name in files:
    # Chop off client_root.
    archive_file_name = input_file_name[ len(client_root) : ]
    # Replace back slash with forward slash. So we do not have Windows paths.
    archive_file_name = archive_file_name.replace("\\", "/")
    # Open input file and add it to the archive.
    with open(input_file_name, 'rb') as input_file:
      tarInfo = tarfile.TarInfo(name=archive_file_name)
      input_file.seek(0,2)
      tarInfo.size = input_file.tell()
      tarInfo.mtime = 0  # For deterministic builds.
      input_file.seek(0)
      tar.addfile(tarInfo, fileobj=input_file)
  tar.close()
  if compress:
    with open(tar_path, "rb") as fin:
      uncompressed = fin.read()
    with open(tar_path, "wb") as fout:
      # mtime=0 for deterministic builds.
      gz = gzip.GzipFile(fileobj=fout, mode="wb", filename="", mtime=0)
      gz.write(uncompressed)
      gz.close()


def MakeArchive(options):
  if not options.client_root:
    sys.stderr.write('--client_root not specified')
    return -1

  files = [ ]
  for dirname, dirnames, filenames in os.walk(options.client_root):
    # strip out all dot files.
    filenames = [f for f in filenames if not f[0] == '.']
    dirnames[:] = [d for d in dirnames if not d[0] == '.']
    for f in filenames:
      src_path = os.path.join(dirname, f)
      if (os.path.isdir(src_path)):
          continue
      files.append(src_path)

  # Ensure consistent file ordering for reproducible builds.
  files.sort()

  # Write out archive.
  CreateTarArchive(options.tar_output,
                   options.client_root,
                   options.compress,
                   files)
  return 0


def WriteCCFile(output_file,
                outer_namespace,
                inner_namespace,
                name,
                tar_archive,
                ):
  cc_text = '''
// Copyright (c) %d, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

''' % date.today().year
  cc_text += '''

#if defined(_WIN32)
typedef unsigned __int8 uint8_t;
#else
#include <inttypes.h>
#include <stdint.h>
#endif
#include <stddef.h>

'''
  cc_text += 'namespace %s {\n' % outer_namespace
  if inner_namespace != None:
    cc_text += 'namespace %s {\n' % inner_namespace
  cc_text += '\n\n'
  # Write the archive.
  cc_text += 'static const uint8_t %s_[] = {\n   ' % name
  lineCounter = 0
  for byte in tar_archive:
    cc_text += r" %d," % ord(byte)
    lineCounter += 1
    if lineCounter == 10:
      cc_text += '\n   '
      lineCounter = 0
  if lineCounter != 0:
    cc_text += '\n   '
  cc_text += '\n};\n'
  cc_text += '\nunsigned int %s_len = %d;\n' % (name, len(tar_archive))
  cc_text += '\nconst uint8_t* %s = %s_;\n\n' % (name, name)
  if inner_namespace != None:
    cc_text += '}  // namespace %s\n' % inner_namespace
  cc_text += '} // namespace %s\n' % outer_namespace

  open(output_file, 'w').write(cc_text)


def MakeCCFile(options):
  if not options.output:
    sys.stderr.write('--output not specified\n')
    return -1
  if not options.name:
    sys.stderr.write('--name not specified\n')
    return -1
  if not options.tar_input:
    sys.stderr.write('--tar_input not specified\n')
    return -1

  # Read it back in.
  with open(options.tar_input, 'rb') as tar_file:
    tar_archive = tar_file.read()

  # Write CC file.
  WriteCCFile(options.output,
              options.outer_namespace,
              options.inner_namespace,
              options.name,
              tar_archive)
  return 0


def Main(args):
  try:
    # Parse input.
    parser = OptionParser()
    parser.add_option("--output",
                      action="store", type="string",
                      help="output file name")
    parser.add_option("--tar_input",\
                      action="store", type="string",
                      help="input tar archive")
    parser.add_option("--tar_output",
                      action="store", type="string",
                      help="tar output file name")
    parser.add_option("--outer_namespace",
                      action="store", type="string",
                      help="outer C++ namespace",
                      default="dart")
    parser.add_option("--inner_namespace",
                      action="store", type="string",
                      help="inner C++ namespace",
                      default="bin")
    parser.add_option("--name",
                      action="store", type="string",
                      help="name of tar archive symbol")
    parser.add_option("--compress", action="store_true", default=False)
    parser.add_option("--client_root",
                      action="store", type="string",
                      help="root directory client resources")

    (options, args) = parser.parse_args()

    if options.tar_output:
      return MakeArchive(options)
    else:
      return MakeCCFile(options)

  except Exception, inst:
    sys.stderr.write('create_resources.py exception\n')
    sys.stderr.write(str(inst))
    sys.stderr.write('\n')
    return -1


if __name__ == '__main__':
  sys.exit(Main(sys.argv))
