#!/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',
    'samples_2',
    '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())
