# Copyright (c) 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import json
import os
import subprocess
import sys
import re
from optparse import OptionParser

# This script runs pkg-config, optionally filtering out some results, and
# returns the result.
#
# The result will be [ <includes>, <cflags>, <libs>, <lib_dirs>, <ldflags> ]
# where each member is itself a list of strings.
#
# You can filter out matches using "-v <regexp>" where all results from
# pkgconfig matching the given regular expression will be ignored. You can
# specify more than one regular expression my specifying "-v" more than once.
#
# You can specify a sysroot using "-s <sysroot>" where sysroot is the absolute
# system path to the sysroot used for compiling. This script will attempt to
# generate correct paths for the sysroot.
#
# When using a sysroot, you must also specify the architecture via
# "-a <arch>" where arch is either "x86" or "x64".
#
# Additionally, you can specify the option --atleast-version. This will skip
# the normal outputting of a dictionary and instead print true or false,
# depending on the return value of pkg-config for the given package.

# If this is run on non-Linux platforms, just return nothing and indicate
# success. This allows us to "kind of emulate" a Linux build from other
# platforms.
if sys.platform.find("linux") == -1:
  print "[[],[],[],[],[]]"
  sys.exit(0)


def SetConfigPath(options):
  """Set the PKG_CONFIG_PATH environment variable.
  This takes into account any sysroot and architecture specification from the
  options on the given command line."""

  sysroot = options.sysroot
  if not sysroot:
    sysroot = ""

  # Compute the library path name based on the architecture.
  arch = options.arch
  if sysroot and not arch:
    print "You must specify an architecture via -a if using a sysroot."
    sys.exit(1)
  if arch == 'x64':
    libpath = 'lib64'
  else:
    libpath = 'lib'

  # Add the sysroot path to the environment's PKG_CONFIG_PATH
  config_path = sysroot + '/usr/' + libpath + '/pkgconfig'
  config_path += ':' + sysroot + '/usr/share/pkgconfig'
  if 'PKG_CONFIG_PATH' in os.environ:
    os.environ['PKG_CONFIG_PATH'] += ':' + config_path
  else:
    os.environ['PKG_CONFIG_PATH'] = config_path


def GetPkgConfigPrefixToStrip(args):
  """Returns the prefix from pkg-config where packages are installed.
  This returned prefix is the one that should be stripped from the beginning of
  directory names to take into account sysroots."""
  # Some sysroots, like the Chromium OS ones, may generate paths that are not
  # relative to the sysroot. For example,
  # /path/to/chroot/build/x86-generic/usr/lib/pkgconfig/pkg.pc may have all
  # paths relative to /path/to/chroot (i.e. prefix=/build/x86-generic/usr)
  # instead of relative to /path/to/chroot/build/x86-generic (i.e prefix=/usr).
  # To support this correctly, it's necessary to extract the prefix to strip
  # from pkg-config's |prefix| variable.
  prefix = subprocess.check_output(["pkg-config", "--variable=prefix"] + args,
      env=os.environ)
  if prefix[-4] == '/usr':
    return prefix[4:]
  return prefix


def MatchesAnyRegexp(flag, list_of_regexps):
  """Returns true if the first argument matches any regular expression in the
  given list."""
  for regexp in list_of_regexps:
    if regexp.search(flag) != None:
      return True
  return False


def RewritePath(path, strip_prefix, sysroot):
  """Rewrites a path by stripping the prefix and prepending the sysroot."""
  if os.path.isabs(path) and not path.startswith(sysroot):
    if path.startswith(strip_prefix):
      path = path[len(strip_prefix):]
    path = path.lstrip('/')
    return os.path.join(sysroot, path)
  else:
    return path


parser = OptionParser()
parser.add_option('-p', action='store', dest='pkg_config', type='string',
                  default='pkg-config')
parser.add_option('-v', action='append', dest='strip_out', type='string')
parser.add_option('-s', action='store', dest='sysroot', type='string')
parser.add_option('-a', action='store', dest='arch', type='string')
parser.add_option('--atleast-version', action='store',
                  dest='atleast_version', type='string')
(options, args) = parser.parse_args()

# Make a list of regular expressions to strip out.
strip_out = []
if options.strip_out != None:
  for regexp in options.strip_out:
    strip_out.append(re.compile(regexp))

SetConfigPath(options)
if options.sysroot:
  prefix = GetPkgConfigPrefixToStrip(args)
else:
  prefix = ''

if options.atleast_version:
  # When asking for the return value, just run pkg-config and print the return
  # value, no need to do other work.
  if not subprocess.call([options.pkg_config,
                          "--atleast-version=" + options.atleast_version] +
                          args,
                         env=os.environ):
    print "true"
  else:
    print "false"
  sys.exit(0)

try:
  flag_string = subprocess.check_output(
      [ options.pkg_config, "--cflags", "--libs-only-l", "--libs-only-L" ] +
      args, env=os.environ)
  # For now just split on spaces to get the args out. This will break if
  # pkgconfig returns quoted things with spaces in them, but that doesn't seem
  # to happen in practice.
  all_flags = flag_string.strip().split(' ')
except:
  print "Could not run pkg-config."
  sys.exit(1)


sysroot = options.sysroot
if not sysroot:
  sysroot = ''

includes = []
cflags = []
libs = []
lib_dirs = []
ldflags = []

for flag in all_flags[:]:
  if len(flag) == 0 or MatchesAnyRegexp(flag, strip_out):
    continue;

  if flag[:2] == '-l':
    libs.append(RewritePath(flag[2:], prefix, sysroot))
  elif flag[:2] == '-L':
    lib_dirs.append(RewritePath(flag[2:], prefix, sysroot))
  elif flag[:2] == '-I':
    includes.append(RewritePath(flag[2:], prefix, sysroot))
  elif flag[:3] == '-Wl':
    ldflags.append(flag)
  elif flag == '-pthread':
    # Many libs specify "-pthread" which we don't need since we always include
    # this anyway. Removing it here prevents a bunch of duplicate inclusions on
    # the command line.
    pass
  else:
    cflags.append(flag)

# Output a GN array, the first one is the cflags, the second are the libs. The
# JSON formatter prints GN compatible lists when everything is a list of
# strings.
print json.dumps([includes, cflags, libs, lib_dirs, ldflags])
