#!/usr/bin/env python3
# Copyright 2016 The Android Open Source Project
#
# Licensed 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.

"""Wrapper to run google-java-format to check for any malformatted changes."""

import argparse
import os
import shutil
import sys

_path = os.path.realpath(__file__ + '/../..')
if sys.path[0] != _path:
    sys.path.insert(0, _path)
del _path

# We have to import our local modules after the sys.path tweak.  We can't use
# relative imports because this is an executable program, not a module.
# pylint: disable=wrong-import-position
import rh.shell
import rh.utils


def get_parser():
    """Return a command line parser."""
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('--google-java-format', default='google-java-format',
                        help='The path of the google-java-format executable.')
    parser.add_argument('--google-java-format-diff',
                        default='google-java-format-diff.py',
                        help='The path of the google-java-format-diff script.')
    parser.add_argument('--fix', action='store_true',
                        help='Fix any formatting errors automatically.')
    parser.add_argument('--commit', type=str, default='HEAD',
                        help='Specify the commit to validate.')
    parser.add_argument('--skip-sorting-imports', action='store_true',
                        help='If true, imports will not be sorted.')
    parser.add_argument('files', nargs='*',
                        help='If specified, only consider differences in '
                             'these files.')
    return parser


def main(argv):
    """The main entry."""
    parser = get_parser()
    opts = parser.parse_args(argv)

    format_path = shutil.which(opts.google_java_format)
    if not format_path:
        print(
            f'Unable to find google-java-format at: {opts.google_java_format}',
            file=sys.stderr
        )
        return 1

    # TODO: Delegate to the tool once this issue is resolved:
    # https://github.com/google/google-java-format/issues/107
    diff_cmd = ['git', 'diff', '--no-ext-diff', '-U0', f'{opts.commit}^!']
    diff_cmd.extend(['--'] + opts.files)
    diff = rh.utils.run(diff_cmd, capture_output=True).stdout

    cmd = [opts.google_java_format_diff, '-p1', '--aosp', '-b', format_path]
    if opts.fix:
        cmd.extend(['-i'])
    if opts.skip_sorting_imports:
        cmd.extend(['--skip-sorting-imports'])

    stdout = rh.utils.run(cmd, input=diff, capture_output=True).stdout
    if stdout:
        print('One or more files in your commit have Java formatting errors.')
        print(f'You can run: {sys.argv[0]} --fix {rh.shell.cmd_to_str(argv)}')
        return 1

    return 0


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