#!/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.

"""Utility for dart_pkg and dart_pkg_app rules"""

import argparse
import errno
import json
import os
import shutil
import subprocess
import sys

USE_LINKS = sys.platform != "win32"

DART_ANALYZE = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                            "dart_analyze.py")

def dart_filter(path):
  if os.path.isdir(path):
    return True
  _, ext = os.path.splitext(path)
  # .dart includes '.mojom.dart'
  return ext == '.dart'


def ensure_dir_exists(path):
  abspath = os.path.abspath(path)
  if not os.path.exists(abspath):
    os.makedirs(abspath)


def has_pubspec_yaml(paths):
  for path in paths:
    _, filename = os.path.split(path)
    if 'pubspec.yaml' == filename:
      return True
  return False


def link(from_root, to_root):
  ensure_dir_exists(os.path.dirname(to_root))
  try:
    os.unlink(to_root)
  except OSError as e:
    if e.errno == errno.ENOENT:
      pass

  try:
    os.symlink(from_root, to_root)
  except OSError as e:
    if e.errno == errno.EEXIST:
      pass


def copy(from_root, to_root, filter_func=None):
  if not os.path.exists(from_root):
    return
  if os.path.isfile(from_root):
    ensure_dir_exists(os.path.dirname(to_root))
    shutil.copy(from_root, to_root)
    return

  ensure_dir_exists(to_root)

  for root, dirs, files in os.walk(from_root):
    # filter_func expects paths not names, so wrap it to make them absolute.
    wrapped_filter = None
    if filter_func:
      wrapped_filter = lambda name: filter_func(os.path.join(root, name))

    for name in filter(wrapped_filter, files):
      from_path = os.path.join(root, name)
      root_rel_path = os.path.relpath(from_path, from_root)
      to_path = os.path.join(to_root, root_rel_path)
      to_dir = os.path.dirname(to_path)
      if not os.path.exists(to_dir):
        os.makedirs(to_dir)
      shutil.copy(from_path, to_path)

    dirs[:] = filter(wrapped_filter, dirs)


def copy_or_link(from_root, to_root, filter_func=None):
  if USE_LINKS:
    link(from_root, to_root)
  else:
    copy(from_root, to_root, filter_func)


def link_if_possible(from_root, to_root):
  if USE_LINKS:
    link(from_root, to_root)


def remove_if_exists(path):
  try:
    os.remove(path)
  except OSError as e:
    if e.errno != errno.ENOENT:
      raise


def list_files(from_root, filter_func=None):
  file_list = []
  for root, dirs, files in os.walk(from_root):
    # filter_func expects paths not names, so wrap it to make them absolute.
    wrapped_filter = None
    if filter_func:
      wrapped_filter = lambda name: filter_func(os.path.join(root, name))
    for name in filter(wrapped_filter, files):
      path = os.path.join(root, name)
      file_list.append(path)
    dirs[:] = filter(wrapped_filter, dirs)
  return file_list


def remove_broken_symlink(path):
  if not USE_LINKS:
    return
  try:
    link_path = os.readlink(path)
  except OSError as e:
    # Path was not a symlink.
    if e.errno == errno.EINVAL:
      pass
  else:
    if not os.path.exists(link_path):
      remove_if_exists(path)


def remove_broken_symlinks(root_dir):
  if not USE_LINKS:
    return
  for current_dir, _, child_files in os.walk(root_dir):
    for filename in child_files:
      path = os.path.join(current_dir, filename)
      remove_broken_symlink(path)


def analyze_entrypoints(dart_sdk, package_root, entrypoints):
  cmd = [ "python", DART_ANALYZE ]
  cmd.append("--dart-sdk")
  cmd.append(dart_sdk)
  cmd.append("--entrypoints")
  cmd.extend(entrypoints)
  cmd.append("--package-root")
  cmd.append(package_root)
  cmd.append("--no-hints")
  try:
    subprocess.check_output(cmd, stderr=subprocess.STDOUT)
  except subprocess.CalledProcessError as e:
    print('Failed analyzing %s' % entrypoints)
    print(e.output)
    return e.returncode
  return 0


def main():
  parser = argparse.ArgumentParser(description='Generate a dart-pkg')
  parser.add_argument('--dart-sdk',
                      action='store',
                      metavar='dart_sdk',
                      help='Path to the Dart SDK.')
  parser.add_argument('--package-name',
                      action='store',
                      metavar='package_name',
                      help='Name of package',
                      required=True)
  parser.add_argument('--pkg-directory',
                      metavar='pkg_directory',
                      help='Directory where dart_pkg should go',
                      required=True)
  parser.add_argument('--package-root',
                      metavar='package_root',
                      help='packages/ directory',
                      required=True)
  parser.add_argument('--stamp-file',
                      metavar='stamp_file',
                      help='timestamp file',
                      required=True)
  parser.add_argument('--entries-file',
                      metavar='entries_file',
                      help='script entries file',
                      required=True)
  parser.add_argument('--package-sources',
                      metavar='package_sources',
                      help='Package sources',
                      nargs='+')
  parser.add_argument('--package-entrypoints',
                      metavar='package_entrypoints',
                      help='Package entry points for analyzer',
                      nargs='*',
                      default=[])
  parser.add_argument('--sdk-ext-directories',
                      metavar='sdk_ext_directories',
                      help='Directory containing .dart sources',
                      nargs='*',
                      default=[])
  parser.add_argument('--sdk-ext-files',
                      metavar='sdk_ext_files',
                      help='List of .dart files that are part of of sdk_ext.',
                      nargs='*',
                      default=[])
  parser.add_argument('--sdk-ext-mappings',
                      metavar='sdk_ext_mappings',
                      help='Mappings for SDK extension libraries.',
                      nargs='*',
                      default=[])
  parser.add_argument('--read_only',
                      action='store_true',
                      dest='read_only',
                      help='Package is a read only package.',
                      default=False)
  args = parser.parse_args()

  # We must have a pubspec.yaml.
  assert has_pubspec_yaml(args.package_sources)

  target_dir = os.path.join(args.pkg_directory, args.package_name)
  target_packages_dir = os.path.join(target_dir, 'packages')
  lib_path = os.path.join(target_dir, "lib")
  ensure_dir_exists(lib_path)

  mappings = {}
  for mapping in args.sdk_ext_mappings:
    library, path = mapping.split(',', 1)
    mappings[library] = '../sdk_ext/%s' % path

  sdkext_path = os.path.join(lib_path, '_sdkext')
  if mappings:
    with open(sdkext_path, 'w') as stream:
      json.dump(mappings, stream, sort_keys=True,
                indent=2, separators=(',', ': '))
  else:
    remove_if_exists(sdkext_path)

  # Copy or symlink package sources into pkg directory.
  common_source_prefix = os.path.dirname(os.path.commonprefix(
      args.package_sources))
  for source in args.package_sources:
    relative_source = os.path.relpath(source, common_source_prefix)
    target = os.path.join(target_dir, relative_source)
    copy_or_link(source, target)

  entrypoint_targets = []
  for source in args.package_entrypoints:
    relative_source = os.path.relpath(source, common_source_prefix)
    target = os.path.join(target_dir, relative_source)
    copy_or_link(source, target)
    entrypoint_targets.append(target)

  # Copy sdk-ext sources into pkg directory
  sdk_ext_dir = os.path.join(target_dir, 'sdk_ext')
  for directory in args.sdk_ext_directories:
    sdk_ext_sources = list_files(directory, dart_filter)
    common_prefix = os.path.commonprefix(sdk_ext_sources)
    for source in sdk_ext_sources:
      relative_source = os.path.relpath(source, common_prefix)
      target = os.path.join(sdk_ext_dir, relative_source)
      copy_or_link(source, target)

  common_source_prefix = os.path.dirname(os.path.commonprefix(
      args.sdk_ext_files))
  for source in args.sdk_ext_files:
    relative_source = os.path.relpath(source, common_source_prefix)
    target = os.path.join(sdk_ext_dir, relative_source)
    copy_or_link(source, target)

  # Symlink packages/
  package_path = os.path.join(args.package_root, args.package_name)
  copy_or_link(lib_path, package_path)

  # Link dart-pkg/$package/packages to dart-pkg/packages
  link_if_possible(args.package_root, target_packages_dir)

  # Remove any broken symlinks in target_dir and package root.
  remove_broken_symlinks(target_dir)
  remove_broken_symlinks(args.package_root)

  # If any entrypoints are defined, write them to disk so that the analyzer
  # test can find them.
  with open(args.entries_file, 'w') as f:
    for entrypoint in entrypoint_targets:
      f.write(entrypoint + '\n')

  # Write stamp file.
  with open(args.stamp_file, 'w'):
    pass

  return 0

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