#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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.

"""Add or check license header

Usuage:

- add the default license header to source files that do not contain a valid
  license:

  python license_header.py add

- check if every files has a license header

  python license_header.py check
"""

import re
import os
import argparse
from itertools import chain
import logging
import sys

# the default apache license
_LICENSE = """Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you 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."""

# if a file contains any str in the list, then consider it has been licensed
_LICENSE_PATTERNS = ['Licensed to the Apache Software Foundation']

# the folders or files that will be ignored
_WHITE_LIST = ['R-package/',
               'docker/Dockerfiles',
               '3rdparty',
               'src/operator/mkl/',
               'src/operator/special_functions-inl.h',
               'src/operator/nn/pool.h',
               'src/operator/contrib/psroi_pooling-inl.h',
               'src/operator/contrib/nn/deformable_im2col.h',
               'src/operator/contrib/nn/deformable_im2col.cuh',
               'src/operator/nn/im2col.h',
               'src/operator/nn/im2col.cuh',
               'example/ssd/dataset/pycocotools/coco.py',
               'example/rcnn/rcnn/cython/setup.py',
               'example/rcnn/rcnn/cython/nms_kernel.cu',
               'prepare_mkl.sh',
               'example/image-classification/predict-cpp/image-classification-predict.cc',
               'src/operator/contrib/ctc_include/']

# language extensions and the according commment mark
_LANGS = {'.cc':'*', '.h':'*', '.cu':'*', '.cuh':'*', '.py':'#',
          '.pm':'#', '.scala':'*', '.cc':'*', '.sh':'#', '.cmake':'#',
          '.java':'*', '.sh':'#', '.cpp':'*', '.hpp':'*', '.c':'*',
          '.bat':'rem', '.pl':'#', '.m':'%', '.R':'#', '.mk':'#', '.cfg':'#', '.t':'#', '.ps1': '#'}

# Previous license header, which will be removed
_OLD_LICENSE = re.compile('.*Copyright.*by Contributors')

def _has_license(lines):
    return any([any([p in l for p in _LICENSE_PATTERNS]) for l in lines])

def _get_license(comment_mark):
    if comment_mark == '*':
        body = '/*\n'
    else:
        body = ''
    for l in _LICENSE.split('\n'):
        if comment_mark == '*':
            body += ' '
        body += comment_mark
        if len(l):
            body += ' ' + l
        body += '\n'

    if comment_mark == '*':
        body += ' */\n'
    body += '\n'
    return body

def _valid_file(fname, verbose=False):
    if any([l in fname for l in _WHITE_LIST]):
        if verbose:
            logging.info('skip ' + fname + ', it matches the white list')
        return False
    _, ext = os.path.splitext(fname)
    if ext not in _LANGS:
        if verbose:
            logging.info('skip ' + fname + ', unknown file extension')
        return False
    return True

def process_file(fname, action, verbose=True):
    if not _valid_file(fname, verbose):
        return True
    with open(fname, 'r', encoding="utf-8") as f:
        lines = f.readlines()
    if not lines:
        return True
    if _has_license(lines):
        return True
    elif action == 'check':
        return False
    _, ext = os.path.splitext(fname)
    with open(fname, 'w', encoding="utf-8") as f:
        # shebang line
        if lines[0].startswith('#!'):
            f.write(lines[0].rstrip()+'\n\n')
            del lines[0]
        f.write(_get_license(_LANGS[ext]))
        for l in lines:
            f.write(l.rstrip()+'\n')
    logging.info('added license header to ' + fname)
    return True

def process_folder(root, action):
    excepts = []
    for root, _, files in os.walk(root):
        for f in files:
            fname = os.path.normpath(os.path.join(root, f))
            if not process_file(fname, action):
                excepts.append(fname)
    if action == 'check' and excepts:
        logging.warning('The following files do not contain a valid license, '+
                        'you can use `python tools/license_header.py add [file]` to add'+
                        'them automatically: ')
        for x in excepts:
            logging.warning(x)
        return False
    return True

if __name__ == '__main__':
    logging.getLogger().setLevel(logging.INFO)
    logging.basicConfig(format='%(asctime)-15s %(message)s')
    parser = argparse.ArgumentParser(
        description='Add or check source license header')
    parser.add_argument(
        'action', nargs=1, type=str,
        choices=['add', 'check'], default='add',
        help = 'add or check')

    parser.add_argument(
        'file', nargs='*', type=str, action='append',
        help='Files to add license header to')

    args = parser.parse_args()
    files = list(chain(*args.file))
    action = args.action[0]
    has_license = True
    if len(files) > 0:
        for file in files:
            has_license = process_file(file, action)
            if action == 'check' and not has_license:
                logging.warn("{} doesn't have a license".format(file))
                has_license = False
    else:
        has_license = process_folder(os.path.join(os.path.dirname(__file__), '..'), action)
    if not has_license:
        sys.exit(1)
    else:
        sys.exit(0)

