#!/usr/bin/env python
# Copyright 2015 The PDFium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

from __future__ import print_function

import os

# pylint: disable=relative-import
import common


class Suppressor:

  def __init__(self, finder, features, js_disabled, xfa_disabled):
    self.has_v8 = not js_disabled and 'V8' in features
    self.has_xfa = not js_disabled and not xfa_disabled and 'XFA' in features
    self.suppression_set = self._LoadSuppressedSet('SUPPRESSIONS', finder)
    self.image_suppression_set = self._LoadSuppressedSet(
        'SUPPRESSIONS_IMAGE_DIFF', finder)

  def _LoadSuppressedSet(self, suppressions_filename, finder):
    v8_option = "v8" if self.has_v8 else "nov8"
    xfa_option = "xfa" if self.has_xfa else "noxfa"
    with open(os.path.join(finder.TestingDir(), suppressions_filename)) as f:
      return set(
          self._FilterSuppressions(common.os_name(), v8_option, xfa_option,
                                   self._ExtractSuppressions(f)))

  def _ExtractSuppressions(self, f):
    return [
        y.split(' ') for y in [x.split('#')[0].strip()
                               for x in f.readlines()] if y
    ]

  def _FilterSuppressions(self, os_name, js, xfa, unfiltered_list):
    return [
        x[0]
        for x in unfiltered_list
        if self._MatchSuppression(x, os_name, js, xfa)
    ]

  def _MatchSuppression(self, item, os_name, js, xfa):
    os_column = item[1].split(",")
    js_column = item[2].split(",")
    xfa_column = item[3].split(",")
    return (('*' in os_column or os_name in os_column) and
            ('*' in js_column or js in js_column) and
            ('*' in xfa_column or xfa in xfa_column))

  def IsResultSuppressed(self, input_filename):
    if input_filename in self.suppression_set:
      print("%s result is suppressed" % input_filename)
      return True
    return False

  def IsExecutionSuppressed(self, input_filepath):
    if "xfa_specific" in input_filepath and not self.has_xfa:
      print("%s execution is suppressed" % input_filepath)
      return True
    return False

  def IsImageDiffSuppressed(self, input_filename):
    if input_filename in self.image_suppression_set:
      print("%s image diff comparison is suppressed" % input_filename)
      return True
    return False
