#!/usr/bin/env python2
# -*- coding: utf-8 -*-
# Copyright 2018 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Find patches that are missing from stable kernels."""

from __future__ import print_function

import argparse
import base64
import os
import sys

import config
import simpledb
import utils


class PatchFinderException(Exception):
    """Exceptions raised by PatchFinder."""


class PatchFinder(object):
    """PatchFinder locates patches that are absent in stable kernels."""
    DEFAULTS = {
        '414': (config.SRC_LINUX_STABLE_414_DB, 'linux-4.14.y'),
        '44': (config.SRC_LINUX_STABLE_44_DB, 'linux-4.4.y'),
    }

    def __init__(self, kver, objfiles):
        self.kver = kver
        self.dbname, self.branch = PatchFinder.DEFAULTS[self.kver]

        self.assert_dbs_exist()

        self.db = simpledb.SimpleDB(self.dbname)
        self.mainline = simpledb.SimpleDB(config.SRC_LINUX_DB)

        contents = open(os.path.expanduser(objfiles)).readlines()
        objfiles = [i.strip() for i in contents]
        self.srcfiles = [i[2:-2] + '.c' for i in objfiles if i.endswith('.o')]
        self.stats = {}

    def assert_dbs_exist(self):
        "Check if caches exist, else raise PatchFinderException."""
        if not os.path.isfile(self.dbname):
            raise PatchFinderException('%s not found, create with dbgen.py'
                                       % (self.dbname))

        if not os.path.isfile(config.SRC_LINUX_DB):
            raise PatchFinderException('%s not found, create with dbgen.py'
                                       % (config.SRC_LINUX_DB))

    def commit_in_stable(self, title):
        """Returns true if |title| is a commit present in stable."""
        stable_commit = self.db.find_one(title=title)
        if not stable_commit:
            return False
        return True

    def commit_is_interesting(self, files):
        """Returns true if a in |files| is used in a kernel build."""
        return any(i in files for i in self.srcfiles)

    def process(self):
        """PatchFinder core."""
        print('Mainline commit count=%d' % (self.mainline.count()))
        commits = self.mainline.all()

        for counter, commit in enumerate(commits):
            if (counter+1) % 100000 == 0:
                print('--- %d' % (counter+1))

            body, files = (base64.b64decode(i) for i in
                           [commit['body'], commit['files']])
            files = [i for i in files.splitlines() if i]

            if not utils.interesting_keyword_in(body):
                continue

            if self.commit_in_stable(commit['title']):
                utils.incstats(self.stats, 'commit_already_in_stable')
                continue

            if not self.commit_is_interesting(files):
                utils.incstats(self.stats, 'commit_is_not_interesting')
                continue

            causer = utils.fixes_stmt(body)
            if not causer:
                continue

            cstr = utils.commitstr(causer)
            if not cstr:
                utils.incstats(self.stats, 'fixes_stmt_unparseable')
                continue

            if not self.commit_in_stable(cstr):
                utils.incstats(self.stats, 'root_cause_present')
                continue

            print('Missing commit: %s ("%s")'
                  % (commit['commitid'][:10], commit['title']))
            utils.incstats(self.stats, 'count')

    def dump_stats(self):
        """Print stats related to missing commits."""
        print(self.stats)


def get_parser():
    """Create and return an ArgumentParser instance."""
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('--kver', type=str, required=True,
                        choices=['414', '44'],
                        help='Choose one of supported kernel versions')
    parser.add_argument('--objfiles', type=str, required=True,
                        help='objfiles to use for filtering results')
    return parser


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

    p = PatchFinder(opts.kver, opts.objfiles)

    p.process()
    p.dump_stats()


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