#!/usr/bin/env python

# Copyright 2017 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import argparse
import os
import os.path
import shutil
import subprocess
import sys
import stat
import tempfile

# How to patch libxml2 in Chromium:
#
# 1. Write a .patch file and add it to third_party/libxml/chromium.
# 2. Apply the patch in src: patch -p1 <../chromium/foo.patch
# 3. Add the patch to the list of patches in this file.
# 4. Update README.chromium with the provenance of the patch.
# 5. Upload a change with the modified documentation, roll script,
#    patch, applied patch and any other relevant changes like
#    regression tests. Go through the usual review and commit process.
#
# How to roll libxml2 in Chromium:
#
# Prerequisites:
#
# 1. Check out Chromium somewhere on Linux, Mac and Windows.
# 2. On Linux:
#    a. sudo apt-get install libicu-dev
#    b. git clone https://github.com/GNOME/libxml2.git somewhere
# 3. On Mac, install these packages with brew:
#      autoconf automake libtool pkgconfig icu4c
#
#    Important! Before running roll.py, set these environmental variables so the
#    configure script can find ICU:
#      export LDFLAGS="-L/path/to/homebrew/opt/icu4c/lib"
#      export CPPFLAGS="-I/path/to/homebrew/opt/icu4c/include"
#      export PKG_CONFIG_PATH="/path/to/homebrew/opt/icu4c/lib/pkgconfig"
#
# Procedure:
#
# Warning: This process is destructive. Run it on a clean branch.
#
# 1. On Linux, in the libxml2 repo directory:
#    a. git remote update origin
#    b. git checkout origin/master
#
#    This will be the upstream version of libxml you are rolling to.
#
# 2. On Linux, in the Chromium src director:
#    a. third_party/libxml/chromium/roll.py --linux /path/to/libxml2
#
#    If this fails, it may be a patch no longer applies. Reset to
#    head; modify the patch files, this script, and
#    README.chromium; then commit the result and run it again.
#
#    b. Upload a CL, but do not Start Review.
#
# 2. On Windows, in the Chromium src directory:
#    a. git cl patch <Gerrit Issue ID>
#    b. third_party\libxml\chromium\roll.py --win32
#    c. git cl upload
#
# 3. On Mac, in the Chromium src directory:
#    a. git cl patch <Gerrit Issue ID>
#    b. third_party/libxml/chromium/roll.py --mac
#    c. Make and commit any final changes to README.chromium, BUILD.gn, etc.
#    d. git cl upload
#    e. Complete the review as usual

PATCHES = [
    # TODO(dcheng): reach out upstream to see what's going on here.
    'revert-non-recursive-xml-parsing.patch',
    'chromium-issue-599427.patch',
    'chromium-issue-628581.patch',
    'libxml2-2.9.4-security-xpath-nodetab-uaf.patch',
    'chromium-issue-708434.patch',
    # TODO(dcheng): Merge this back upstream.
    'add-missing-ifdef-in-xml-reader.patch',
]


# See libxml2 configure.ac and win32/configure.js to learn what
# options are available. We include every option here to more easily track
# changes from one version to the next, and to be sure we only include what
# we need.
# These two sets of options should be in sync. You can check the
# generated #defines in (win32|mac|linux)/include/libxml/xmlversion.h to confirm
# this.
# We would like to disable python but it introduces a host of build errors
SHARED_XML_CONFIGURE_OPTIONS = [
    # These options are turned ON
    ('--with-html', 'html=yes'),
    ('--with-icu', 'icu=yes'),
    ('--with-output', 'output=yes'),
    ('--with-push', 'push=yes'),
    ('--with-python', 'python=yes'),
    ('--with-reader', 'reader=yes'),
    ('--with-sax1', 'sax1=yes'),
    ('--with-tree', 'tree=yes'),
    ('--with-writer', 'writer=yes'),
    ('--with-xpath', 'xpath=yes'),
    # These options are turned OFF
    ('--without-c14n', 'c14n=no'),
    ('--without-catalog', 'catalog=no'),
    ('--without-debug', 'xml_debug=no'),
    ('--without-docbook', 'docb=no'),
    ('--without-ftp', 'ftp=no'),
    ('--without-http', 'http=no'),
    ('--without-iconv', 'iconv=no'),
    ('--without-iso8859x', 'iso8859x=no'),
    ('--without-legacy', 'legacy=no'),
    ('--without-lzma', 'lzma=no'),
    ('--without-mem-debug', 'mem_debug=no'),
    ('--without-modules', 'modules=no'),
    ('--without-pattern', 'pattern=no'),
    ('--without-regexps', 'regexps=no'),
    ('--without-run-debug', 'run_debug=no'),
    ('--without-schemas', 'schemas=no'),
    ('--without-schematron', 'schematron=no'),
    ('--without-threads', 'threads=no'),
    ('--without-valid', 'valid=no'),
    ('--without-xinclude', 'xinclude=no'),
    ('--without-xptr', 'xptr=no'),
    ('--without-zlib', 'zlib=no'),
]


# These options are only available in configure.ac for Linux and Mac.
EXTRA_NIX_XML_CONFIGURE_OPTIONS = [
    '--without-fexceptions',
    '--without-minimum',
    '--without-readline',
    '--without-history',
]


# These options are only available in win32/configure.js for Windows.
EXTRA_WIN32_XML_CONFIGURE_OPTIONS = [
    'trio=no',
    'walker=no',
]


XML_CONFIGURE_OPTIONS = (
    [option[0] for option in SHARED_XML_CONFIGURE_OPTIONS] +
    EXTRA_NIX_XML_CONFIGURE_OPTIONS)


XML_WIN32_CONFIGURE_OPTIONS = (
    [option[1] for option in SHARED_XML_CONFIGURE_OPTIONS] +
    EXTRA_WIN32_XML_CONFIGURE_OPTIONS)


FILES_TO_REMOVE = [
    'src/DOCBparser.c',
    'src/HACKING',
    'src/INSTALL',
    'src/INSTALL.libxml2',
    'src/MAINTAINERS',
    'src/Makefile.in',
    'src/Makefile.win',
    'src/README.cvs-commits',
    # This is unneeded "legacy" SAX API, even though we enable SAX1.
    'src/SAX.c',
    'src/VxWorks',
    'src/autogen.sh',
    'src/autom4te.cache',
    'src/bakefile',
    'src/build_glob.py',
    'src/c14n.c',
    'src/catalog.c',
    'src/compile',
    'src/config.guess',
    'src/config.sub',
    'src/configure',
    'src/chvalid.def',
    'src/debugXML.c',
    'src/depcomp',
    'src/doc',
    'src/example',
    'src/genChRanges.py',
    'src/global.data',
    'src/include/libxml/Makefile.in',
    'src/include/libxml/xmlversion.h',
    'src/include/libxml/xmlwin32version.h',
    'src/include/libxml/xmlwin32version.h.in',
    'src/include/Makefile.in',
    'src/install-sh',
    'src/legacy.c',
    'src/libxml2.doap',
    'src/ltmain.sh',
    'src/m4',
    'src/macos/libxml2.mcp.xml.sit.hqx',
    'src/missing',
    'src/optim',
    'src/os400',
    'src/python',
    'src/relaxng.c',
    'src/result',
    'src/rngparser.c',
    'src/schematron.c',
    'src/test',
    'src/testOOM.c',
    'src/testOOMlib.c',
    'src/testOOMlib.h',
    'src/trio.c',
    'src/trio.h',
    'src/triop.h',
    'src/triostr.c',
    'src/triostr.h',
    'src/vms',
    'src/win32/VC10/config.h',
    'src/win32/wince',
    'src/xinclude.c',
    'src/xlink.c',
    'src/xml2-config.in',
    'src/xmlcatalog.c',
    'src/xmllint.c',
    'src/xmlmodule.c',
    'src/xmlregexp.c',
    'src/xmlschemas.c',
    'src/xmlschemastypes.c',
    'src/xpointer.c',
    'src/xstc',
    'src/xzlib.c',
]


THIRD_PARTY_LIBXML_SRC = 'third_party/libxml/src'


class WorkingDir(object):
    """"Changes the working directory and resets it on exit."""
    def __init__(self, path):
        self.prev_path = os.getcwd()
        self.path = path

    def __enter__(self):
        os.chdir(self.path)

    def __exit__(self, exc_type, exc_value, traceback):
        if exc_value:
            print('was in %s; %s before that' % (self.path, self.prev_path))
        os.chdir(self.prev_path)


def git(*args):
    """Runs a git subcommand.

    On Windows this uses the shell because there's a git wrapper
    batch file in depot_tools.

    Arguments:
        args: The arguments to pass to git.
    """
    command = ['git'] + list(args)
    subprocess.check_call(command, shell=(os.name == 'nt'))


def remove_tracked_and_local_dir(path):
    """Removes the contents of a directory from git, and the filesystem.

    Arguments:
        path: The path to remove.
    """
    remove_tracked_files([path])
    shutil.rmtree(path, ignore_errors=True)
    os.mkdir(path)


def remove_tracked_files(files_to_remove):
    """Removes tracked files from git.

    Arguments:
        files_to_remove: The files to remove.
    """
    files_to_remove = [f for f in files_to_remove if os.path.exists(f)]
    if files_to_remove:
        git('rm', '-rf', *files_to_remove)


def sed_in_place(input_filename, program):
    """Replaces text in a file.

    Arguments:
        input_filename: The file to edit.
        program: The sed program to perform edits on the file.
    """
    # OS X's sed requires -e
    subprocess.check_call(['sed', '-i', '-e', program, input_filename])


def check_copying(full_path_to_third_party_libxml_src):
    path = os.path.join(full_path_to_third_party_libxml_src, 'COPYING')
    if not os.path.exists(path):
        return
    with open(path) as f:
        s = f.read()
        if 'GNU' in s:
            raise Exception('check COPYING')


def prepare_libxml_distribution(src_path, libxml2_repo_path, temp_dir):
    """Makes a libxml2 distribution.

    Args:
        src_path: The path to the Chromium checkout.
        libxml2_repo_path: The path to the local clone of the libxml2 repo.
        temp_dir: A temporary directory to stage the distribution to.

    Returns: A tuple of commit hash and full path to the archive.
    """
    # If it was necessary to push from a distribution prepared upstream,
    # this is the point to inject it: Return the version string and the
    # distribution tar file.

    # The libxml2 repo we're pulling changes from should not have
    # local changes. This *should* be a commit that's publicly visible
    # in the upstream repo; reviewers should check this.
    check_clean(libxml2_repo_path)

    temp_config_path = os.path.join(temp_dir, 'config')
    os.mkdir(temp_config_path)
    temp_src_path = os.path.join(temp_dir, 'src')
    os.mkdir(temp_src_path)

    with WorkingDir(libxml2_repo_path):
        commit = subprocess.check_output(
            ['git', 'log', '-n', '1', '--pretty=format:%H', 'HEAD'])
        subprocess.check_call(
            'git archive HEAD | tar -x -C "%s"' % temp_src_path,
            shell=True)
    with WorkingDir(temp_src_path):
        os.remove('.gitignore')
        for patch in PATCHES:
            print('applying %s' % patch)
            subprocess.check_call(
                'patch -p1 --fuzz=0 < %s' % os.path.join(
                    src_path, THIRD_PARTY_LIBXML_SRC, '..', 'chromium', patch),
                shell=True)

    with WorkingDir(temp_config_path):
        print('../src/autogen.sh %s' % XML_CONFIGURE_OPTIONS)
        subprocess.check_call(['../src/autogen.sh'] + XML_CONFIGURE_OPTIONS)
        subprocess.check_call(['make', 'dist-all'])

        # Work out what it is called
        tar_file = subprocess.check_output(
            '''awk '/PACKAGE =/ {p=$3} /VERSION =/ {v=$3} '''
            '''END {printf("%s-%s.tar.gz", p, v)}' Makefile''',
            shell=True)
        return commit, os.path.abspath(tar_file)


def roll_libxml_linux(src_path, libxml2_repo_path):
    with WorkingDir(src_path):
        # Export the upstream git repo.
        try:
            temp_dir = tempfile.mkdtemp()
            print('temporary directory: %s' % temp_dir)

            commit, tar_file = prepare_libxml_distribution(
                src_path, libxml2_repo_path, temp_dir)

            # Remove all of the old libxml to ensure only desired cruft
            # accumulates
            remove_tracked_and_local_dir(THIRD_PARTY_LIBXML_SRC)

            # Update the libxml repo and export it to the Chromium tree
            with WorkingDir(THIRD_PARTY_LIBXML_SRC):
                subprocess.check_call(
                    'tar xzf %s --strip-components=1' % tar_file,
                    shell=True)
        finally:
            shutil.rmtree(temp_dir)

        with WorkingDir(THIRD_PARTY_LIBXML_SRC):
            # Put the version number is the README file
            sed_in_place('../README.chromium',
                         's/Version: .*$/Version: %s/' % commit)

            with WorkingDir('../linux'):
                subprocess.check_call(
                    ['../src/autogen.sh'] + XML_CONFIGURE_OPTIONS)
                check_copying(os.getcwd())
                sed_in_place('config.h', 's/#define HAVE_RAND_R 1//')

            # Add *everything*
            with WorkingDir('../src'):
                git('add', '*')
                git('commit', '-am', '%s libxml, linux' % commit)
    print('Now push to Windows and run steps there.')


def roll_libxml_win32(src_path):
    with WorkingDir(src_path):
        # Run the configure script.
        with WorkingDir(os.path.join(THIRD_PARTY_LIBXML_SRC, 'win32')):
            subprocess.check_call(
                ['cscript', '//E:jscript', 'configure.js', 'compiler=msvc'] +
                XML_WIN32_CONFIGURE_OPTIONS)

            # Add and commit the result.
            shutil.move('VC10/config.h', '../../win32/config.h')
            git('add', '../../win32/config.h')
            shutil.move('../include/libxml/xmlversion.h',
                        '../../win32/include/libxml/xmlversion.h')
            git('add', '../../win32/include/libxml/xmlversion.h')
            git('commit', '-m', 'Windows')
            git('clean', '-f')
    print('Now push to Mac and run steps there.')


def roll_libxml_mac(src_path):
    full_path_to_third_party_libxml = os.path.join(
        src_path, THIRD_PARTY_LIBXML_SRC, '..')

    with WorkingDir(os.path.join(full_path_to_third_party_libxml, 'mac')):
        subprocess.check_call(['autoreconf', '-i', '../src'])
        os.chmod('../src/configure',
                 os.stat('../src/configure').st_mode | stat.S_IXUSR)
        subprocess.check_call(['../src/configure'] + XML_CONFIGURE_OPTIONS)
        sed_in_place('config.h', 's/#define HAVE_RAND_R 1//')

    with WorkingDir(full_path_to_third_party_libxml):
        commit = subprocess.check_output(['awk', '/Version:/ {print $2}',
                                          'README.chromium'])
        remove_tracked_files(FILES_TO_REMOVE)
        commit_message = 'Roll libxml to %s' % commit
        git('commit', '-am', commit_message)
    print('Now upload for review, etc.')


def check_clean(path):
    with WorkingDir(path):
        status = subprocess.check_output(['git', 'status', '-s'])
        if len(status) > 0:
            raise Exception('repository at %s is not clean' % path)


def main():
    src_dir = os.getcwd()
    if not os.path.exists(os.path.join(src_dir, 'third_party')):
        print('error: run this script from the Chromium src directory')
        sys.exit(1)

    parser = argparse.ArgumentParser(
        description='Roll the libxml2 dependency in Chromium')
    platform = parser.add_mutually_exclusive_group(required=True)
    platform.add_argument('--linux', action='store_true')
    platform.add_argument('--win32', action='store_true')
    platform.add_argument('--mac', action='store_true')
    parser.add_argument(
        'libxml2_repo_path',
        type=str,
        nargs='?',
        help='The path to the local clone of the libxml2 git repo.')
    args = parser.parse_args()

    if args.linux:
        libxml2_repo_path = args.libxml2_repo_path
        if not libxml2_repo_path:
            print('Specify the path to the local libxml2 repo clone.')
            sys.exit(1)
        libxml2_repo_path = os.path.abspath(libxml2_repo_path)
        roll_libxml_linux(src_dir, libxml2_repo_path)
    elif args.win32:
        roll_libxml_win32(src_dir)
    elif args.mac:
        roll_libxml_mac(src_dir)


if __name__ == '__main__':
    main()
