#!/usr/bin/env python3

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