#!/usr/bin/python
# Copyright 2015 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Create the initial board build directory and config files."""

from __future__ import print_function

import argparse
import getpass
import grp
import logging
import multiprocessing
import os
import sys


def GetParser():
  parser = argparse.ArgumentParser(description=__doc__)
  parser.add_argument('--board', type=str, required=True,
                      help='The board to use')
  return parser


def main(argv):
  parser = GetParser()
  opts = parser.parse_args(argv)

  source_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(
      os.path.realpath(__file__)))))

  overlay = os.path.join(source_root, 'src', 'overlays', 'overlay-%s' % opts.board)
  if not os.path.exists(overlay):
    print('overaly does not exist: %s' % overlay)

  sysroot = os.path.join(source_root, 'build', opts.board)
  print('Setting up %s' % sysroot)

  # Create /etc/portage/.
  etc_portage = os.path.join(sysroot, 'etc', 'portage')
  if not os.path.isdir(etc_portage):
    os.makedirs(etc_portage)

  # Create /etc/portage/make.profile.
  target = os.path.relpath(os.path.join(overlay, 'profiles', 'base'),
                           etc_portage)
  profile = os.path.join(etc_portage, 'make.profile')
  if not os.path.islink(profile):
    os.symlink(target, profile)

  # Stub a few packages out.
  profile = os.path.join(etc_portage, 'profile')
  if not os.path.isdir(profile):
    os.makedirs(profile)
  conf = os.path.join(profile, 'package.provided')
  with open(conf, 'w') as f:
    f.write("""# AUTO GENERATED.
# We use the git eclass which wants git to build things, but we don't actually
# need it in the sysroot as it's a host tool.  Stub it out.
dev-vcs/git-2
""")

  # Used by generation below.
  settings = {
      'source_root': source_root,
      'sysroot': sysroot,
      'overlay': overlay,
      'gprefix': os.path.join(source_root, 'src', 'third_party',
                              'portage-prefix'),
      'ncpus': multiprocessing.cpu_count(),
      'username': getpass.getuser(),
      'groupname': grp.getgrgid(os.getgid()).gr_name,
      'uid': os.getuid(),
      'gid': os.getgid(),
  }

  # Create /etc/portage/make.conf.
  conf = os.path.join(etc_portage, 'make.conf')
  with open(conf, 'w') as f:
    f.write("""# AUTO GENERATED.
EPREFIX='/'
SOURCE_ROOT="%(source_root)s"
CHROOT_SOURCE_ROOT="${SOURCE_ROOT}"
ANDROID_SOURCE="${SOURCE_ROOT}/android"
GENTOO_PREFIX="%(gprefix)s"
COMMON_BUILD="${SOURCE_ROOT}/build/portage"
DISTDIR="${COMMON_BUILD}/distdir"
ROOT="%(sysroot)s"
PORTAGE_TMPDIR="${ROOT}/tmp"
PORT_LOGDIR="${PORTAGE_TMPDIR}/logs"
SYSROOT="%(sysroot)s"
ROOTPATH="/usr/bin:/bin:/usr/sbin:/sbin:${GENTOO_PREFIX}/usr/bin"
ARCH="amd64"
BOARD_OVERLAY="%(overlay)s"
BOARD_USE="bruteus"
CHOST="x86_64-cros-linux-gnu"
MAKEOPTS="-j%(ncpus)i"
PKG_CONFIG="${SYSROOT}/build/bin/pkg-config"
PKGDIR="${SYSROOT}/packages"
PORTDIR_OVERLAY="${SOURCE_ROOT}/src/third_party/eclass-overlay
${SOURCE_ROOT}/src/third_party/portage-stable
${SOURCE_ROOT}/src/third_party/chromiumos-overlay
%(overlay)s"
source "${BOARD_OVERLAY}/make.conf"
PORTAGE_BUNZIP2_COMMAND="bzip2"
FEATURES="-sandbox -usersandbox"
EMERGE_DEFAULT_OPTS="--root-deps --quiet-build y --jobs %(ncpus)i"

TC_GCC_BASE="${ANDROID_SOURCE}/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/bin"
TC_CLANG_BASE="${ANDROID_SOURCE}/prebuilts/clang/linux-x86/host/3.6/bin"
CC="${TC_CLANG_BASE}/clang"
CXX="${CXX}++"
AR="${TC_GCC_BASE}/x86_64-linux-ar"
RANLIB="${TC_GCC_BASE}/x86_64-linux-ranlib"
STRIP="${TC_GCC_BASE}/x86_64-linux-strip"

CBUILD="x86_64-pc-linux-gnu"
CHOST="x86_64-android-linux-gnu"

# TODO: These should be pushed back into portage itself.
PORTAGE_USER='%(username)s'
PORTAGE_GROUP='%(groupname)s'
PORTAGE_ROOT_USER='%(username)s'
PORTAGE_INST_UID='%(uid)s'
PORTAGE_INST_GID='%(gid)s'
""" % settings)

  # Now a few bin wrappers.
  bindir = os.path.join(sysroot, 'build', 'bin')
  if not os.path.isdir(bindir):
    os.makedirs(bindir)

  for wrapper in ('ebuild', 'emerge', 'portageq'):
    target = os.path.join(bindir, wrapper)
    settings['wrapper'] = wrapper
    with open(target, 'w') as f:
      f.write("""#!/bin/sh
PORTAGE_CONFIGROOT="%(sysroot)s" \
ROOT="%(sysroot)s" \
exec "%(gprefix)s/usr/bin/%(wrapper)s" "$@"
""" % settings)
    os.chmod(target, 0o755)

  # Done!
  print('You may now use the programs in %s' % bindir)


if __name__ == '__main__':
  sys.exit(main(sys.argv[1:]))
