#!/usr/bin/env python3
#
# 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, dirname
sys.path.append(join(dirname(__file__), '..'))
import utils

HOST_OS = utils.GuessOS()
DART_DIR = abspath(join(dirname(__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 = [
    'buildtools/linux-x64/go',
    'buildtools/linux-x64/rust',
    'samples',
    'third_party/7zip',
    'third_party/android_tools',
    'third_party/clang',
    'third_party/d8',
    'third_party/firefox_jsshell',
    'third_party/gsutil',
    'third_party/llvm-build',
    'third_party/mdn',
]
ignoredDirs = [
    '.cipd',
    '.git',
    'benchmarks',
    'docs',
    'fuchsia',
    'parser_testcases',
    'testcases',
    'tests',
]
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())
