#!/usr/bin/env python
#
# Copyright (c) 2014, 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.
#

# Script to build a tarball of the Dart source.
#
# The tarball includes all the source needed to build Dart. This
# includes source in third_party. As part of creating the tarball the
# files used to build Debian packages are copied to a top-level debian
# directory. This makes it easy to build Debian packages from the
# tarball.
#
# For building a Debian package one need to the tarball to follow the
# Debian naming rules upstream tar files.
#
#  $ mv dart-XXX.tar.gz dart_XXX.orig.tar.gz
#  $ tar xf dart_XXX.orig.tar.gz
#  $ cd dart_XXX
#  $ debuild -us -uc

import datetime
import optparse
import sys
import tarfile
from os import listdir
from os.path import join, split, abspath

import utils


HOST_OS = utils.GuessOS()
DART_DIR = abspath(join(__file__, '..', '..'))
# Flags.
verbose = False

# Name of the dart directory when unpacking the tarball.
versiondir = ''

# Ignore Git/SVN files, checked-in binaries, backup files, etc..
ignoredPaths = ['third_party/7zip', 'third_party/android_tools',
                'third_party/clang', 'third_party/d8',
                'third_party/firefox_jsshell']
ignoredDirs = ['.svn', '.git']
ignoredEndings = ['.mk', '.pyc', 'Makefile', '~']

def BuildOptions():
  result = optparse.OptionParser()
  result.add_option("-v", "--verbose",
      help='Verbose output.',
      default=False, action="store_true")
  result.add_option("--tar_filename",
                    default=None,
                    help="The output file.")

  return result

def Filter(tar_info):
  # Get the name of the file relative to the dart directory. Note the
  # name from the TarInfo does not include a leading slash.
  assert tar_info.name.startswith(DART_DIR[1:])
  original_name = tar_info.name[len(DART_DIR):]
  _, tail = split(original_name)
  if tail in ignoredDirs:
    return None
  for path in ignoredPaths:
    if original_name.startswith(path):
      return None
  for ending in ignoredEndings:
    if original_name.endswith(ending):
      return None
  # Add the dart directory name with version. Place the debian
  # directory one level over the rest which are placed in the
  # directory 'dart'. This enables building the Debian packages
  # out-of-the-box.
  tar_info.name = join(versiondir, 'dart', original_name)
  if verbose:
    print 'Adding %s as %s' % (original_name, tar_info.name)
  return tar_info

def GenerateCopyright(filename):
  with open(join(DART_DIR, 'LICENSE')) as lf:
    license_lines = lf.readlines()

  with open(filename, 'w') as f:
    f.write('Name: dart\n')
    f.write('Maintainer: Dart Team <misc@dartlang.org>\n')
    f.write('Source: https://code.google.com/p/dart/\n')
    f.write('License:\n')
    for line in license_lines:
      f.write(' %s' % line)  # Line already contains trailing \n.

def GenerateChangeLog(filename, version):
  with open(filename, 'w') as f:
    f.write('dart (%s-1) UNRELEASED; urgency=low\n' % version)
    f.write('\n')
    f.write('  * Generated file.\n')
    f.write('\n')
    f.write(' -- Dart Team <misc@dartlang.org>  %s\n' %
            datetime.datetime.utcnow().strftime('%a, %d %b %Y %X +0000'))

def GenerateEmpty(filename):
  f = open(filename, 'w')
  f.close()

def GenerateGitRevision(filename, git_revision):
  with open(filename, 'w') as f:
    f.write(str(git_revision))


def CreateTarball(tarfilename):
  global ignoredPaths  # Used for adding the output directory.
  # Generate the name of the tarfile
  version = utils.GetVersion()
  global versiondir
  versiondir = 'dart-%s' % version
  debian_dir = 'tools/linux_dist_support/debian'
  # Don't include the build directory in the tarball (ignored paths
  # are relative to DART_DIR).
  builddir = utils.GetBuildDir(HOST_OS)
  ignoredPaths.append(builddir)

  print 'Creating tarball: %s' % tarfilename
  with tarfile.open(tarfilename, mode='w:gz') as tar:
    for f in listdir(DART_DIR):
      tar.add(join(DART_DIR, f), filter=Filter)
    for f in listdir(join(DART_DIR, debian_dir)):
      tar.add(join(DART_DIR, debian_dir, f),
              arcname='%s/debian/%s' % (versiondir, f))

    with utils.TempDir() as temp_dir:
      # Generate and add debian/copyright
      copyright_file = join(temp_dir, 'copyright')
      GenerateCopyright(copyright_file)
      tar.add(copyright_file, arcname='%s/debian/copyright' % versiondir)

      # Generate and add debian/changelog
      change_log = join(temp_dir, 'changelog')
      GenerateChangeLog(change_log, version)
      tar.add(change_log, arcname='%s/debian/changelog' % versiondir)

      # For generated version file build dependency, add fake git reflog.
      empty = join(temp_dir, 'empty')
      GenerateEmpty(empty)
      tar.add(empty, arcname='%s/dart/.git/logs/HEAD' % versiondir)

      # For bleeding_edge add the GIT_REVISION file.
      if utils.GetChannel() == 'be':
        git_revision = join(temp_dir, 'GIT_REVISION')
        GenerateGitRevision(git_revision, utils.GetGitRevision())
        tar.add(git_revision, arcname='%s/dart/tools/GIT_REVISION' % versiondir)

def Main():
  if HOST_OS != 'linux':
    print 'Tarball can only be created on linux'
    return -1

  # Parse the options.
  parser = BuildOptions()
  (options, args) = parser.parse_args()
  if options.verbose:
    global verbose
    verbose = True

  tar_filename = options.tar_filename
  if not tar_filename:
    tar_filename = join(DART_DIR,
                        utils.GetBuildDir(HOST_OS),
                        'dart-%s.tar.gz' % utils.GetVersion())

  CreateTarball(tar_filename)

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