# Copyright (c) 2012 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.

"""
Generate a file that sets the specified board's binhosts to include all of the
other compatible boards in this buildroot.
"""

import collections
import glob
import optparse
import os
import sys

from chromite.buildbot import cbuildbot_config
from chromite.lib import cros_build_lib

def FindCandidateBoards(board):
  """Find candidate local boards to grab prebuilts from."""
  board_no_variant = board.partition("_")[0]
  portageq_prefix = "/usr/local/bin/portageq-"
  for path in sorted(glob.glob("%s*" % portageq_prefix)):
    # Strip off the portageq prefix, leaving only the board.
    other_board = path.replace(portageq_prefix, "")

    # It is only safe to inherit prebuilts from generic boards, or from the
    # same board without the variant. This rule helps keep inheritance trees
    # sane.
    if (other_board in cbuildbot_config.generic_boards or
        other_board == board_no_variant or other_board == board):
      yield other_board


def SummarizeCompatibility(board):
  """Returns a string that will be the same for compatible boards."""
  cmd = ["portageq-%s" % board, "envvar", "ARCH", "CFLAGS"]
  return cros_build_lib.RunCommand(cmd, redirect_stdout=True,
                                   print_cmd=False).output.rstrip()


def GenerateBinhostLine(build_root, compatible_boards):
  """Generate a binhost line pulling binaries from the specified boards."""
  local_binhosts = " ".join([
      "file://localhost" + os.path.join(build_root, x, "packages")
      for x in sorted(compatible_boards)])
  return "LOCAL_BINHOST='%s'" % local_binhosts


def main(argv):
  parser = optparse.OptionParser(usage="USAGE: ./%prog --board=board [options]")

  parser.add_option("--build_root", default="/build",
                    dest="build_root",
                    help="Location of boards (normally /build)")
  parser.add_option("--board", default=None,
                    dest="board",
                    help="Board name (required).")

  flags, remaining_arguments = parser.parse_args(argv)

  if remaining_arguments or not flags.board:
    parser.print_help()
    sys.exit(1)

  by_compatibility = collections.defaultdict(set)
  compatible_boards = None
  for other_board in FindCandidateBoards(flags.board):
    compat_id = SummarizeCompatibility(other_board)
    if other_board == flags.board:
      compatible_boards = by_compatibility[compat_id]
    else:
      by_compatibility[compat_id].add(other_board)

  if compatible_boards is None:
    print >> sys.stderr, "Missing portageq wrapper for %s" % flags.board
    sys.exit(1)

  # If a non-generic prebuilt is available, ignore the generic ones,
  # since the non-generic ones will be better matches.
  compatible_specific_boards = \
      compatible_boards - set(cbuildbot_config.generic_boards)
  if compatible_specific_boards:
    compatible_boards = compatible_specific_boards

  print "# Generated by cros_generate_local_binhosts."
  print GenerateBinhostLine(flags.build_root, compatible_boards)
