#!/usr/bin/env python

# Copyright (c) 2020 ARM Limited
# All rights reserved
#
# The license below extends only to copyright in the software and shall
# not be construed as granting a license to any other intellectual
# property including but not limited to intellectual property relating
# to a hardware implementation of the functionality of the software
# licensed hereunder.  You may use the software subject to the license
# terms below provided that you ensure that this notice is replicated
# unmodified and in its entirety in all distributions of the software,
# modified or unmodified, in source code or in binary form.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# 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;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "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 THE COPYRIGHT
# OWNER 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.

import argparse
import datetime
import subprocess
import sys

import git_filter_repo

import update_copyright

parser = argparse.ArgumentParser(description=
"""Update copyright headers on files of a range of commits.

This can be used to easily update copyright headers at once on an entire
patchset before submitting.

Only files touched by the selected commits are updated.

Only existing copyrights for the selected holder are updated, new
notices are never automatically added if not already present.

The size of the changes is not taken into account, every touched file gets
updated. If you want to undo that for a certain file because the change to
it is trivial, you need to manually rebase and undo the copyright change
for that file.

Example usage with an organization alias such as `arm`:

```
python3 -m pip install --user --requirement \
  gem5/util/update_copyright/requirements.txt
./update-copyright.py -o arm HEAD~3
```

The above would act on the 3 last commits (HEAD~2, HEAD~ and HEAD),
leaving HEAD~3 unchanged, and doing updates such as:

```
- * Copyright (c) 2010, 2012-2013, 2015,2017-2019 ARM Limited
+ * Copyright (c) 2010, 2012-2013, 2015,2017-2020 ARM Limited
```

If the organization is not in the alias list, you can also explicitly give
the organization string as in:

```
./update-copyright.py HEAD~3 'ARM Limited'
```

which is equivalent to the previous invocation.
""",
    formatter_class=argparse.RawTextHelpFormatter,
)
parser.add_argument('start',
        nargs='?',
        help="The commit before the last commit to be modified")
parser.add_argument('org-string',
        nargs='?',
        help="Copyright holder name")
parser.add_argument('-o', '--org', choices=('arm',),
        help="Alias for known organizations")
args = parser.parse_args()

def error(msg):
    print('error: ' + msg, file=sys.stderr)
    sys.exit(1)

# The existing safety checks are too strict, so we just disable them
# with force, and do our own checks to not overwrite uncommited changes
# checks.
# https://github.com/newren/git-filter-repo/issues/159
if subprocess.call(['git', 'diff', '--staged', '--quiet']):
    error("uncommitted changes")
if subprocess.call(['git', 'diff', '--quiet']):
    error("unstaged changes")

# Handle CLI arguments.
if args.start is None:
    error("the start argument must be given")
if args.org is None and getattr(args, 'org-string') is None:
    error("either --org or org-string must be given")
if args.org is not None and getattr(args, 'org-string') is not None:
    error("both --org and org-string given")
if args.org is not None:
    org_bytes = update_copyright.org_alias_map[args.org]
else:
    org_bytes = getattr(args, 'org-string').encode()

# Call git_filter_repo.
# Args deduced from:
# print(git_filter_repo.FilteringOptions.parse_args(['--refs', 'HEAD',
# '--force'], error_on_empty=False))
filter_repo_args = git_filter_repo.FilteringOptions.default_options()
filter_repo_args.force = True
filter_repo_args.partial = True
filter_repo_args.refs = ['{}..HEAD'.format(args.start)]
filter_repo_args.repack=False
filter_repo_args.replace_refs='update-no-add'
def blob_callback(blob, callback_metadata, org_bytes):
    blob.data = update_copyright.update_copyright(blob.data,
        datetime.datetime.now().year, org_bytes)
git_filter_repo.RepoFilter(
    filter_repo_args,
    blob_callback=lambda x, y: blob_callback( x, y, org_bytes)
).run()
