#!/usr/bin/env python3
#
# Copyright 2022 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# This script performs most of the steps required to complete a roll of the
# Fuchsia ffmpeg repository. It reads a 'profile set' file containing a list
# of absolute paths to 'profile' files. A profile file contains a list of
# command line arguments for the ffmpeg 'configure' script. Those command line
# arguments determine which features are enabled for the profile in question.
# The base name of a profile file must be <profile>_args, where <profile> is the
# name of the profile.
#
# This script performs two make-based builds of ffmpeg for each profile, one
# build for x64 and one for arm64. The resulting artifacts are deposited in a
# temporary directory (the '--roll-dir' option, './roll' by default). It then
# generates ffmpeg_generated.gni, a config/ directory, and CREDITS.fuchsia.
#
# A complete roll consists of the following steps:
#
# 1) Ensure that the most recent commit of the Fuchsia ffmpeg repository is
#    present at //build/secondary/third_party/ffmpeg.
# 2) Ensure that the most recent commit of the Chromium ffmpeg repository is
#    present at //third_party/ffmpeg/src.
# 3) Delete //build/secondary/third_party/ffmpeg/config and ensure the roll
#    directory (usually //build/secondary/third_party/ffmpeg/roll) is absent
#    or empty.
# 4) Run this script.
# 5) Update README.fuchsia to reflect the new Chromium ffmpeg repo commit.
# 6) Submit the changes to the Fuchsia ffmpeg repo.

import argparse
import os
import subprocess
import sys


def PrintAndCheckCall(argv, *args, **kwargs):
    print("")
    print("Running %s" % "\n ".join(argv))
    print("")
    subprocess.check_call(argv, *args, **kwargs)


def main(argv):
    parser = argparse.ArgumentParser(
        epilog="Option defaults assume cwd is build/secondary/third_party/ffmpeg"
    )

    parser.add_argument(
        "profile_set_path",
        metavar="<profile set>",
        help="file containing profile set paths",
    )

    parser.add_argument(
        "--roll-dir",
        default="./roll",
        metavar="<path>",
        help="directory for build output (default: ./roll)",
    )

    parser.add_argument(
        "--fuchsia-src-dir",
        metavar="<path>",
        help="directory containing Fuchsia source code",
    )

    parser.add_argument(
        "--ffmpeg-src-dir",
        metavar="<path>",
        help="directory containing ffmpeg source code",
    )

    parser.add_argument(
        "--ffmpeg-dir",
        default=".",
        metavar="<path>",
        help="directory containing config/ and CREDITS.fuchsia",
    )

    args = parser.parse_args(argv)

    # Read the profile set from the provided path.
    profile_set = []
    with open(args.profile_set_path, "r") as f:
        profile_set = f.read().splitlines()

    # Pass on relevant options to roll_build.py.
    common_build_args = []

    if args.fuchsia_src_dir:
        common_build_args.append("--fuchsia-src-dir=" + args.fuchsia_src_dir)

    if args.ffmpeg_src_dir:
        common_build_args.append("--ffmpeg-src-dir=" + args.ffmpeg_src_dir)

    # Run the 'make' build for each profile, both architectures.
    for profile_path in profile_set:
        py = os.path.join(args.ffmpeg_dir, "scripts", "roll_build.py")
        x64_cmd = [
            py,
            args.roll_dir,
            profile_path,
            "x64",
        ]
        arm64_cmd = [
            py,
            args.roll_dir,
            profile_path,
            "arm64",
        ]

        PrintAndCheckCall(x64_cmd + common_build_args)
        PrintAndCheckCall(arm64_cmd + common_build_args)

    # Pass on relevant options to roll_gen.py.
    gen_args = []

    if args.ffmpeg_dir:
        gen_args.append("--ffmpeg-dir=" + args.ffmpeg_dir)

    if args.ffmpeg_src_dir:
        gen_args.append("--ffmpeg-src-dir=" + args.ffmpeg_src_dir)

    # Generate ffmpeg_generated.gni, config/, and CREDITS.fuchsia from the 'make' build artifacts.
    PrintAndCheckCall(
        [os.path.join(args.ffmpeg_dir, "scripts", "roll_gen.py")]
        + [args.roll_dir]
        + gen_args
    )

    return 0


if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))
