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

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())
