#!/usr/bin/env python
# vim: set ft=python:
# -*- coding: utf-8 -*-
#
# Copyright (C) 2018 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. 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.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 APPLE INC. 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.


# Extract dependency information from the output of `make -d`, generating a
# list of top-level targets (which are assumed to be generated/output files)
# and a list of leaf dependencies (which are assumed to be the base input
# files). Read the make dependency information from stdin and write the results
# to the specified files.


from __future__ import print_function

import argparse
import re
import sys


class Parser(object):

    fileNamePattern         = r"`([^']+)'"
    rePrerequisite          = re.compile(r"Prerequisite {} is .* than target {}".format(fileNamePattern, fileNamePattern))
    reMustRemakeTarget      = re.compile(r"Must remake target {}".format(fileNamePattern))
    reWasConsideredAlready  = re.compile(r"{} was considered already.".format(fileNamePattern))
    rePruningFile           = re.compile(r"Pruning file {}.".format(fileNamePattern))

    def __init__(self):
        self.targets = {}
        self.prereqs = {}

    def nextLine(self, input):
        while True:
            line = input.readline()
            if not line: break
            line = line.strip()
            if line: yield line

    def addTarget(self, target):
        if target != 'all' and target != 'force':
            self.targets[target] = 1

    def addPrereq(self, prereq):
        if prereq != 'all' and prereq != 'force':
            self.prereqs[prereq] = 1

    def doParse(self, input):

        # Pull out everything that looks like a target or prerequisite.

        for line in self.nextLine(input):
            m = Parser.rePrerequisite.search(line)
            if m:
                self.addTarget(m.group(2))
                self.addPrereq(m.group(1))
                continue

            m = Parser.reMustRemakeTarget.search(line)
            if m:
                self.addTarget(m.group(1))
                continue

            m = Parser.reWasConsideredAlready.search(line)
            if m:
                self.addTarget(m.group(1))
                continue

            m = Parser.rePruningFile.search(line)
            if m:
                self.addPrereq(m.group(1))
                continue

        # Regarding prerequisites, we're interested in only those that aren't
        # also targets. We only want ones that don't have build rules, and
        # hence must already exist. Those are our inputs.

        for key in self.targets.keys():
            self.prereqs.pop(key, None)

    def printInputs(self, inputsFile):
        with open(inputsFile, 'w') as toFile:
            [ print("{}".format(f), file = toFile) for f in sorted(self.prereqs.keys()) ]

    def printOutputs(self, outputsFile):
        with open(outputsFile, 'w') as toFile:
            [ print("{}".format(f), file = toFile) for f in sorted(self.targets.keys()) ]


def parseArgs():
    parser = argparse.ArgumentParser()

    parser.add_argument(
        '--input',
        metavar='<xcfilelist>',
        type=str,
        required = True,
        help='path to the xcfilelist holding input files')

    parser.add_argument(
        '--output',
        metavar='<xcfilelist>',
        type=str,
        required = True,
        help='path to the xcfilelist holding output/generated files')

    return parser.parse_args()


def main():
    args = parseArgs()
    parser = Parser()

    parser.doParse(sys.stdin)
    parser.printInputs(args.input)
    parser.printOutputs(args.output)


if __name__ == '__main__':
    main()
