# 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')
parser.add_option('--libdir', action='store_true', dest='libdir')
(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)

if options.libdir:
    try:
        libdir = subprocess.check_output(
            [options.pkg_config, "--variable=libdir"] + args, env=os.environ)
    except:
        print("Error from pkg-config.")
        sys.exit(1)
    sys.stdout.write(libdir.strip())
    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]))
