#!/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 Debian packages from a Dart tarball. The script
# will build a source package and a 32-bit (i386) and 64-bit (amd64)
# binary packages.

import optparse
import os
import sys
import tarfile
import subprocess
from os.path import join, exists, abspath, dirname
sys.path.append(join(dirname(__file__), '..'))
import utils
from shutil import copyfile

HOST_OS = utils.GuessOS()
HOST_CPUS = utils.GuessCpus()
DART_DIR = abspath(join(dirname(__file__), '..', '..'))


def BuildOptions():
    result = optparse.OptionParser()
    result.add_option("--tar_filename",
                      default=None,
                      help="The tar file to build from.")
    result.add_option("--out_dir",
                      default=None,
                      help="Where to put the packages.")
    result.add_option("-a",
                      "--arch",
                      help='Target architectures (comma-separated).',
                      metavar='[all,ia32,x64,armel,armhf]',
                      default='x64')
    result.add_option("-t",
                      "--toolchain",
                      help='Cross-compilation toolchain prefix',
                      default=None)

    return result


def RunBuildPackage(opt, cwd, toolchain=None):
    env = os.environ.copy()
    if toolchain != None:
        env["TOOLCHAIN"] = '--toolchain=' + toolchain
    cmd = ['dpkg-buildpackage', '-j%d' % HOST_CPUS]
    cmd.extend(opt)
    process = subprocess.check_call(cmd, cwd=cwd, env=env)


def BuildDebianPackage(tarball, out_dir, arch, toolchain):
    version = utils.GetVersion()
    tarroot = 'dart-%s' % version
    origtarname = 'dart_%s.orig.tar.gz' % version

    if not exists(tarball):
        print('Source tarball not found')
        return -1

    with utils.TempDir() as temp_dir:
        origtarball = join(temp_dir, origtarname)
        copyfile(tarball, origtarball)

        with tarfile.open(origtarball) as tar:
            tar.extractall(path=temp_dir)

        # Build source package.
        print("Building source package")
        RunBuildPackage(['-S', '-us', '-uc'], join(temp_dir, tarroot))

        # Build 32-bit binary package.
        if 'ia32' in arch:
            print("Building i386 package")
            RunBuildPackage(['-B', '-ai386', '-us', '-uc'],
                            join(temp_dir, tarroot))

        # Build 64-bit binary package.
        if 'x64' in arch:
            print("Building amd64 package")
            RunBuildPackage(['-B', '-aamd64', '-us', '-uc'],
                            join(temp_dir, tarroot))

        # Build armhf binary package.
        if 'armhf' in arch:
            print("Building armhf package")
            RunBuildPackage(['-B', '-aarmhf', '-us', '-uc'],
                            join(temp_dir, tarroot), toolchain)

        # Build armel binary package.
        if 'armel' in arch:
            print("Building armel package")
            RunBuildPackage(['-B', '-aarmel', '-us', '-uc'],
                            join(temp_dir, tarroot), toolchain)

        # Copy the Debian package files to the build directory.
        debbase = 'dart_%s' % version
        source_package = [
            '%s-1.dsc' % debbase,
            '%s.orig.tar.gz' % debbase,
            '%s-1.debian.tar.xz' % debbase
        ]
        i386_package = ['%s-1_i386.deb' % debbase]
        amd64_package = ['%s-1_amd64.deb' % debbase]
        armhf_package = ['%s-1_armhf.deb' % debbase]
        armel_package = ['%s-1_armel.deb' % debbase]

        for name in source_package:
            copyfile(join(temp_dir, name), join(out_dir, name))
        if 'ia32' in arch:
            for name in i386_package:
                copyfile(join(temp_dir, name), join(out_dir, name))
        if 'x64' in arch:
            for name in amd64_package:
                copyfile(join(temp_dir, name), join(out_dir, name))
        if ('armhf' in arch):
            for name in armhf_package:
                copyfile(join(temp_dir, name), join(out_dir, name))
        if ('armel' in arch):
            for name in armel_package:
                copyfile(join(temp_dir, name), join(out_dir, name))


def Main():
    if HOST_OS != 'linux':
        print('Debian build only supported on linux')
        return -1

    options, args = BuildOptions().parse_args()
    out_dir = options.out_dir
    tar_filename = options.tar_filename
    if options.arch == 'all':
        options.arch = 'ia32,x64,armhf'
    arch = options.arch.split(',')

    if not options.out_dir:
        out_dir = join(DART_DIR, utils.GetBuildDir(HOST_OS))

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

    BuildDebianPackage(tar_filename, out_dir, arch, options.toolchain)


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