#!/usr/bin/env python
#
# Copyright 2013 The Flutter Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
""" Gather the build_id, prefix_dir, and exec_name given the path to executable
    also copies to the specified destination.

    The structure of debug symbols is as follows:
      .build-id/<prefix>/<exec_name>[.debug]
"""

import argparse
import errno
import hashlib
import json
import os
import re
import shutil
import subprocess
import sys
import time


def HashFile(filepath):
  """Calculates the hash of a file without reading it all in memory at once."""
  digest = hashlib.sha1()
  with open(filepath, 'rb') as f:
    while True:
      chunk = f.read(1024*1024)
      if not chunk:
        break
      digest.update(chunk)
  return digest.hexdigest()


def Touch(fname):
  with open(fname, 'a'):
    os.utime(fname, None)


def GetBuildIdParts(exec_path, read_elf):
  sha1_pattern = re.compile(r'[0-9a-fA-F\-]+')
  file_out = subprocess.check_output([read_elf, '-n', exec_path])
  build_id_line = file_out.splitlines()[-1].split()
  if (build_id_line[0] != b'Build' or
      build_id_line[1] != b'ID:' or not
      sha1_pattern.match(str(build_id_line[-1])) or not
      len(build_id_line[-1]) > 2):
    raise Exception('Expected the last line of llvm-readelf to match "Build ID <Hex String>" Got: %s' % file_out)

  build_id = build_id_line[-1]
  return {
      'build_id': build_id.decode('utf-8'),
      'prefix_dir': build_id[:2].decode('utf-8'),
      'exec_name': build_id[2:].decode('utf-8')
  }


def main():
  parser = argparse.ArgumentParser()

  parser.add_argument(
      '--executable-name',
      dest='exec_name',
      action='store',
      required=True,
      help='This is the name of the executable that we wish to layout debug symbols for.'
  )
  parser.add_argument(
      '--executable-path',
      dest='exec_path',
      action='store',
      required=True,
      help='Path to the executable on the filesystem.')
  parser.add_argument(
      '--destination-base',
      dest='dest',
      action='store',
      required=True,
      help='Path to the base directory where the debug symbols are to be laid out.'
  )
  parser.add_argument(
      '--stripped',
      dest='stripped',
      action='store_true',
      default=True,
      help='Executable at the specified path is stripped.')
  parser.add_argument(
      '--unstripped',
      dest='stripped',
      action='store_false',
      help='Executable at the specified path is unstripped.')
  parser.add_argument(
      '--read-elf',
      dest='read_elf',
      action='store',
      required=True,
      help='Path to read-elf executable.')

  args = parser.parse_args()
  assert os.path.exists(args.exec_path)
  assert os.path.exists(args.dest)
  assert os.path.exists(args.read_elf)

  parts = GetBuildIdParts(args.exec_path, args.read_elf)
  dbg_prefix_base = os.path.join(args.dest, parts['prefix_dir'])

  # Multiple processes may be trying to create the same directory.
  # TODO(dnfield): use exist_ok when we upgrade to python 3, rather than try
  try:
    os.makedirs(dbg_prefix_base)
  except OSError as e:
    if e.errno != errno.EEXIST:
      raise

  if not os.path.exists(dbg_prefix_base):
    print('Unable to create directory: %s.' % dbg_prefix_base)
    return 1

  dbg_suffix = ''
  if not args.stripped:
    dbg_suffix = '.debug'
  dbg_file_name = '%s%s' % (parts['exec_name'], dbg_suffix)
  dbg_file_path = os.path.join(dbg_prefix_base, dbg_file_name)

  # If the debug file hasn't changed, don't rewrite the debug and completion
  # file, speeding up incremental builds.
  if os.path.exists(dbg_file_path) and HashFile(args.exec_path) == HashFile(dbg_file_path):
    return 0

  shutil.copyfile(args.exec_path, dbg_file_path)

  # Note this needs to be in sync with fuchsia_debug_symbols.gni
  completion_file = os.path.join(args.dest, '.%s_dbg_success' % args.exec_name)
  Touch(completion_file)

  return 0


if __name__ == '__main__':
  sys.exit(main())
