#!/usr/bin/env python

# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to you under the Apache License, Version
# 2.0 (the "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied. See the License for the specific language governing
# permissions and limitations under the License.

# Check for programs linked with libraries they don't in fact use.
# For example, if a program was linked with -lfoo but doesn't use any
# symbols from libfoo.
#
# The list of programs is gathered by scraping Automake files, which are
# themselves gathered from Autoconf. ldd does the actual business of
# checking for unused dependencies.
#
# There are a couple of manual exceptions listed below, either because
# we deliberately link with an unused library -- possibly for
# convenience -- or because I haven't figured out how to fix it yet.
#
# For now, this only checks the programs that we install,
# but it could potentially check our libraries as well.

import os.path
import re
import subprocess
import sys

config_files_re = re.compile(r'(?<=config_files=").*(?=")')
programs_re = re.compile(r'([^\n ]*_)PROGRAMS \+?= (.*)')


def get_dependencies(program):
    args = [
        './libtool', '--mode=execute', 'ldd', '--unused', '--function-relocs',
        program
    ]
    for dependency in subprocess.Popen(args, stdout=subprocess.PIPE).stdout:
        dependency = dependency.decode('utf-8')[:-1]
        if any(
            map(
                os.path.basename(dependency).startswith,
                [
                    'libdl.so.',      # Because we add -ldl to LIBS
                    'libgcc_s.so.',
                    'libm.so.',       # Why does Libtool call ld with -lm?
                    'libpthread.so.'  # Because we add -lpthread to LIBS
                ])):
            continue

        # Why does Libtool call ld with -lcrypto -lresolv -lssl?
        if os.path.basename(program) == 'traffic_manager':
            if any(
                map(
                    os.path.basename(dependency).startswith, [
                        'libcrypto.so.',
                        'libresolv.so.',
                        'libssl.so.'
                    ])):
                continue

        if re.sub('\s+', '', dependency):
            yield dependency


success = True
filename = 'config.status'
contents = open(filename).read()
config_files = config_files_re.search(contents).group(0)
for filename in config_files.split():
    filename = filename + '.am'
    if os.path.exists(filename):
        contents = open(filename).read()
        contents = contents.replace('\\\n', '')
        for prefix, programs in programs_re.findall(contents):
            if prefix not in [
                'EXTRA_',
                'check_',
                'noinst_'
            ]:
                for program in programs.split():
                    program = os.path.join(os.path.dirname(filename), program)
                    if os.path.exists(program):
                        dependencies = list(get_dependencies(program))
                        if len(dependencies) > 1:
                            success = False
                            print(program)
                            for dependency in dependencies:
                                print(dependency)

if not success:
    sys.exit(1)
