# -*- coding: utf-8 -*-
# Copyright 2019 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.

"""Provides matching utilities."""

from __future__ import print_function

import difflib
import fnmatch
import os


def GetMostLikelyMatchedObject(haystack, needle, name_func=lambda x: x,
                               matched_score_threshold=0.4):
  """Matches objects whose names are most likely matched with target.

  Args:
    haystack (list): Objects to search against.
    needle (str): The name to match.
    name_func (callable): Function to get object name to match. Default is the
      identity function.
    matched_score_threshold (float): The threshold of likelihood to match.
      Must be in the range [0,1]. Default is 0.4.

  Returns:
    A list of entities from |haystack| whose names are likely needle.
  """

  def _Score(obj):
    return difflib.SequenceMatcher(a=name_func(obj), b=needle).ratio()

  return sorted([o for o in haystack if _Score(o) > matched_score_threshold])


def FindFilesMatching(pattern, target='./', cwd=os.curdir, exclude_dirs=()):
  """Search the root directory recursively for matching filenames.

  The |target| and |cwd| args allow manipulating how the found paths are
  returned as well as specifying where the search needs to be executed.

  If our filesystem only has /path/to/example.txt, and our pattern is '*.txt':
  |target|='./', |cwd|='/path'    =>  ./to/example.txt
  |target|='to', |cwd|='/path'    =>  to/example.txt
  |target|='./', |cwd|='/path/to' =>  ./example.txt
  |target|='/path'                =>  /path/to/example.txt
  |target|='/path/to'             =>  /path/to/example.txt

  Args:
    pattern: the pattern used to match the filenames.
    target: the target directory to search.
    cwd: current working directory.
    exclude_dirs: Directories to not include when searching.

  Returns:
    A list of paths of the matched files.
  """
  assert cwd
  assert os.path.exists(cwd)

  # Backup the current working directory before changing it.
  old_cwd = os.getcwd()
  os.chdir(cwd)

  matches = []
  for directory, _, filenames in os.walk(target):
    if any(directory.startswith(e) for e in exclude_dirs):
      # Skip files in excluded directories.
      continue

    for filename in fnmatch.filter(filenames, pattern):
      matches.append(os.path.join(directory, filename))

  # Restore the working directory.
  os.chdir(old_cwd)

  return matches
