#!/usr/bin/env python3
#
# 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
                       ), ('exec_path "%s" does not exist' % args.exec_path)
  assert os.path.exists(args.dest), ('dest "%s" does not exist' % args.dest)
  assert os.path.exists(args.read_elf
                       ), ('read_elf "%s" does not exist' % 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())
