#!/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',
    '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://dart.googlesource.com/sdk\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 GenerateGitTimestamp(filename, git_timestamp):
    with open(filename, 'w') as f:
        f.write(str(git_timestamp))

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 main, add the GIT_REVISION file.
            if utils.GetChannel() in ['main', 'be']:
                git_revision = join(temp_dir, 'GIT_REVISION')
                GenerateGitRevision(git_revision, utils.GetGitRevision())
                tar.add(git_revision,
                        arcname='%s/dart/tools/GIT_REVISION' % versiondir)

            # Add GIT_TIMESTAMP file as git is not available in tarball.
            git_timestamp = join(temp_dir, 'GIT_TIMESTAMP')
            GenerateGitTimestamp(git_timestamp, utils.GetGitTimestamp())
            tar.add(git_timestamp,
                    arcname='%s/dart/tools/GIT_TIMESTAMP' % 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())
