#!/usr/bin/python

'''
Copyright 2013 Google Inc.

Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
'''

'''
Gathers diffs between 2 JSON expectations files, or between actual and
expected results within a single JSON actual-results file,
and generates an old-vs-new diff dictionary.

TODO(epoger): Fix indentation in this file (2-space indents, not 4-space).
'''

# System-level imports
import argparse
import json
import os
import sys
import urllib2

# Imports from within Skia
#
# We need to add the 'gm' directory, so that we can import gm_json.py within
# that directory.  That script allows us to parse the actual-results.json file
# written out by the GM tool.
# Make sure that the 'gm' dir is in the PYTHONPATH, but add it at the *end*
# so any dirs that are already in the PYTHONPATH will be preferred.
#
# This assumes that the 'gm' directory has been checked out as a sibling of
# the 'tools' directory containing this script, which will be the case if
# 'trunk' was checked out as a single unit.
GM_DIRECTORY = os.path.realpath(
    os.path.join(os.path.dirname(os.path.dirname(__file__)), 'gm'))
if GM_DIRECTORY not in sys.path:
    sys.path.append(GM_DIRECTORY)
import gm_json


# Object that generates diffs between two JSON gm result files.
class GMDiffer(object):

    def __init__(self):
        pass

    def _GetFileContentsAsString(self, filepath):
        """Returns the full contents of a file, as a single string.
        If the filename looks like a URL, download its contents.
        If the filename is None, return None."""
        if filepath is None:
            return None
        elif filepath.startswith('http:') or filepath.startswith('https:'):
            return urllib2.urlopen(filepath).read()
        else:
            return open(filepath, 'r').read()

    def _GetExpectedResults(self, contents):
        """Returns the dictionary of expected results from a JSON string,
        in this form:

        {
          'test1' : 14760033689012826769,
          'test2' : 9151974350149210736,
          ...
        }

        We make these simplifying assumptions:
        1. Each test has either 0 or 1 allowed results.
        2. All expectations are of type JSONKEY_HASHTYPE_BITMAP_64BITMD5.

        Any tests which violate those assumptions will cause an exception to
        be raised.

        Any tests for which we have no expectations will be left out of the
        returned dictionary.
        """
        result_dict = {}
        json_dict = gm_json.LoadFromString(contents)
        all_expectations = json_dict[gm_json.JSONKEY_EXPECTEDRESULTS]
        for test_name in all_expectations.keys():
            test_expectations = all_expectations[test_name]
            allowed_digests = test_expectations[
                gm_json.JSONKEY_EXPECTEDRESULTS_ALLOWEDDIGESTS]
            if allowed_digests:
                num_allowed_digests = len(allowed_digests)
                if num_allowed_digests > 1:
                    raise ValueError(
                        'test %s has %d allowed digests' % (
                            test_name, num_allowed_digests))
                digest_pair = allowed_digests[0]
                if digest_pair[0] != gm_json.JSONKEY_HASHTYPE_BITMAP_64BITMD5:
                    raise ValueError(
                        'test %s has unsupported hashtype %s' % (
                            test_name, digest_pair[0]))
                result_dict[test_name] = digest_pair[1]
        return result_dict

    def _GetActualResults(self, contents):
        """Returns the dictionary of actual results from a JSON string,
        in this form:

        {
          'test1' : 14760033689012826769,
          'test2' : 9151974350149210736,
          ...
        }

        We make these simplifying assumptions:
        1. All results are of type JSONKEY_HASHTYPE_BITMAP_64BITMD5.

        Any tests which violate those assumptions will cause an exception to
        be raised.

        Any tests for which we have no actual results will be left out of the
        returned dictionary.
        """
        result_dict = {}
        json_dict = gm_json.LoadFromString(contents)
        all_result_types = json_dict[gm_json.JSONKEY_ACTUALRESULTS]
        for result_type in all_result_types.keys():
            results_of_this_type = all_result_types[result_type]
            if results_of_this_type:
                for test_name in results_of_this_type.keys():
                    digest_pair = results_of_this_type[test_name]
                    if digest_pair[0] != gm_json.JSONKEY_HASHTYPE_BITMAP_64BITMD5:
                        raise ValueError(
                            'test %s has unsupported hashtype %s' % (
                                test_name, digest_pair[0]))
                    result_dict[test_name] = digest_pair[1]
        return result_dict

    def _DictionaryDiff(self, old_dict, new_dict):
        """Generate a dictionary showing the diffs between old_dict and new_dict.
        Any entries which are identical across them will be left out."""
        diff_dict = {}
        all_keys = set(old_dict.keys() + new_dict.keys())
        for key in all_keys:
            if old_dict.get(key) != new_dict.get(key):
                new_entry = {}
                new_entry['old'] = old_dict.get(key)
                new_entry['new'] = new_dict.get(key)
                diff_dict[key] = new_entry
        return diff_dict

    def GenerateDiffDict(self, oldfile, newfile=None):
        """Generate a dictionary showing the diffs:
        old = expectations within oldfile
        new = expectations within newfile

        If newfile is not specified, then 'new' is the actual results within
        oldfile.
        """
        return self.GenerateDiffDictFromStrings(self._GetFileContentsAsString(oldfile),
                                                self._GetFileContentsAsString(newfile))

    def GenerateDiffDictFromStrings(self, oldjson, newjson=None):
        """Generate a dictionary showing the diffs:
        old = expectations within oldjson
        new = expectations within newjson

        If newfile is not specified, then 'new' is the actual results within
        oldfile.
        """
        old_results = self._GetExpectedResults(oldjson)
        if newjson:
            new_results = self._GetExpectedResults(newjson)
        else:
            new_results = self._GetActualResults(oldjson)
        return self._DictionaryDiff(old_results, new_results)


def _Main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        'old',
        help='Path to JSON file whose expectations to display on ' +
        'the "old" side of the diff. This can be a filepath on ' +
        'local storage, or a URL.')
    parser.add_argument(
        'new', nargs='?',
        help='Path to JSON file whose expectations to display on ' +
        'the "new" side of the diff; if not specified, uses the ' +
        'ACTUAL results from the "old" JSON file. This can be a ' +
        'filepath on local storage, or a URL.')
    args = parser.parse_args()
    differ = GMDiffer()
    diffs = differ.GenerateDiffDict(oldfile=args.old, newfile=args.new)
    json.dump(diffs, sys.stdout, sort_keys=True, indent=2)


if __name__ == '__main__':
    _Main()
