# 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".

# 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')
(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 = ''

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])
