# -*- 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.

"""Allowlist functions."""

from __future__ import print_function

import glob
import os
import re


# Matching a string of length m in an NFA of size n is O(mn^2), but the
# performance also depends largely on the implementation. It appears to be fast
# enough according to the tests.
#
# The performance bottleneck of this script is readelf. Unless this becomes
# slower than readelf, don't waste time here.
def is_allowlisted(list_name, pattern):
  """Check whether the given pattern is specified in the allowlist.

  Args:
    list_name: name of the allowlist.
    pattern: the target string.

  Returns:
    True if matched otherwise False.
  """
  return pattern and allowlists[list_name].match(pattern)


def prepare_allowlist(patterns):
  """Join and compile the re patterns.

  Args:
    patterns: regex patterns.

  Returns:
    A compiled re object.
  """
  return re.compile('|'.join(patterns))


def load_allowlists(dirname):
  """Load allowlists under dirname.

  An allowlist ends with .allowlist.

  Args:
    dirname: path to the dir.

  Returns:
    A dictionary of 'filename' -> allowlist matcher.
  """
  wlist = {}
  for fn in glob.glob(os.path.join(dirname, '*.allowlist')):
    key = os.path.splitext(os.path.basename(fn))[0]
    with open(fn, 'r', encoding='utf-8') as f:
      patterns = f.read().splitlines()
      patterns = [l for l in patterns if l != '']
      patterns = [l for l in patterns if l[0] != '#']
    wlist[key] = prepare_allowlist(patterns)
  return wlist


allowlists = load_allowlists(os.path.dirname(__file__))
