#!/usr/bin/env python
# Copyright (c) 2013 The Chromium Authors. All rights reserved.
# Copyright (c) 2020-2024 Project CHIP Authors
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#    * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#    * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#    * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from __future__ import print_function

import json
import os
import re
import subprocess
import sys
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".
#
# CrOS systemroots place pkgconfig files at <systemroot>/usr/share/pkgconfig
# and one of <systemroot>/usr/lib/pkgconfig or <systemroot>/usr/lib64/pkgconfig
# depending on whether the systemroot is for a 32 or 64 bit architecture. They
# specify the 'lib' or 'lib64' of the pkgconfig path by defining the
# 'system_libdir' variable in the args.gn file. pkg_config.gni communicates this
# variable to this script with the "--system_libdir <system_libdir>" flag. If no
# flag is provided, then pkgconfig files are assumed to come from
# <systemroot>/usr/lib/pkgconfig.
#
# 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.


def SetConfigPath(options):
    """Set the PKG_CONFIG_LIBDIR environment variable.

    This takes into account any sysroot and architecture specification from the
    options on the given command line.
    """

    sysroot = options.sysroot
    assert sysroot

    libdir = sysroot + '/usr/' + options.system_libdir + '/pkgconfig'
    libdir += ':' + sysroot + '/usr/share/pkgconfig'
    os.environ['PKG_CONFIG_LIBDIR'] = libdir
    return libdir


def GetPkgConfigPrefixToStrip(options, 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([options.pkg_config,
                                      "--variable=prefix"] + args, env=os.environ).decode('utf-8')
    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) is not 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)
    return path


def main():
    parser = OptionParser()
    parser.add_option('-d', '--debug', action='store_true')
    parser.add_option('-o', '--optional', action='store_true')
    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('--system_libdir', action='store', dest='system_libdir',
                      type='string', default='lib')
    parser.add_option('--atleast-version', action='store',
                      dest='atleast_version', type='string')
    parser.add_option('--libdir', action='store_true', dest='libdir')
    parser.add_option('--dridriverdir', action='store_true',
                      dest='dridriverdir')
    parser.add_option('--version-as-components', action='store_true',
                      dest='version_as_components')
    parser.add_option('--static', action='store_true',
                      dest='static')
    (options, args) = parser.parse_args()

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

    if options.sysroot:
        libdir = SetConfigPath(options)
        if options.debug:
            sys.stderr.write('PKG_CONFIG_LIBDIR=%s\n' % libdir)
        prefix = GetPkgConfigPrefixToStrip(options, 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):
            print("true")
        else:
            print("false")
        return 0

    if options.version_as_components:
        cmd = [options.pkg_config, "--modversion"] + args
        try:
            version_string = subprocess.check_output(cmd).decode('utf-8')
        except Exception:
            sys.stderr.write('Error from pkg-config.\n')
            return 1
        print(json.dumps(list(map(int, version_string.strip().split(".")))))
        return 0

    if options.libdir:
        cmd = [options.pkg_config, "--variable=libdir"] + args
        if options.debug:
            sys.stderr.write('Running: %s\n' % cmd)
        try:
            libdir = subprocess.check_output(cmd).decode('utf-8')
        except Exception:
            print("Error from pkg-config.")
            return 1
        sys.stdout.write(libdir.strip())
        return 0

    if options.dridriverdir:
        cmd = [options.pkg_config, "--variable=dridriverdir"] + args
        if options.debug:
            sys.stderr.write('Running: %s\n' % cmd)
        try:
            dridriverdir = subprocess.check_output(cmd).decode('utf-8')
        except Exception:
            print("Error from pkg-config.")
            return 1
        sys.stdout.write(dridriverdir.strip())
        return None

    cmd = [options.pkg_config, "--cflags", "--libs"]

    if options.static:
        cmd.append("--static")

    cmd.extend(args)

    if options.debug:
        sys.stderr.write('Running: %s\n' % ' '.join(cmd))

    try:
        flag_string = subprocess.check_output(cmd).decode('utf-8')
    except Exception:
        if options.optional:
            sys.stderr.write('Ignoring failure to run pkg-config for optional library.\n')
            print(json.dumps([False]))  # Output a GN array indicating missing optional packages
            return 0
        sys.stderr.write('Could not run pkg-config.\n')
        return 1

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

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

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

    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':
            # Don't allow libraries to control ld flags.  These should be specified
            # only in build files.
            pass
        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, indicating success and our output lists.
    # JSON formatter prints GN compatible lists when everything is a list of
    # strings.
    print(json.dumps([True, includes, cflags, libs, lib_dirs]))
    return 0


if __name__ == '__main__':
    sys.exit(main())
