# Copyright (c) 2011 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Some utility methods for getting and manipulating paths."""

# TODO(pamg): Have the buildbot use these, too.


import errno
import os
import sys

class PathNotFound(Exception): pass

def ScriptDir():
  """Get the full path to the directory containing the current script."""
  script_filename = os.path.abspath(sys.argv[0])
  return os.path.dirname(script_filename)

def FindAncestor(start_dir, ancestor):
  """Finds an ancestor dir in a path.

  For example, FindAncestor('c:\foo\bar\baz', 'bar') would return
  'c:\foo\bar'.  Unlike FindUpward*, this only looks at direct path ancestors.
  """
  start_dir = os.path.abspath(start_dir)
  path = start_dir
  while True:
    (parent, tail) = os.path.split(path)
    if tail == ancestor:
      return path
    if not tail:
      break
    path = parent
  raise PathNotFound("Unable to find ancestor %s in %s" % (ancestor, start_dir))

def FindUpwardParent(start_dir, *desired_list):
  """Finds the desired object's parent, searching upward from the start_dir.

  Searches start_dir and all its parents looking for the desired directory
  or file, which may be given in one or more path components. Returns the
  first directory in which the top desired path component was found, or raises
  PathNotFound if it wasn't.
  """
  desired_path = os.path.join(*desired_list)
  last_dir = ''
  cur_dir = start_dir
  found_path = os.path.join(cur_dir, desired_path)
  while not os.path.exists(found_path):
    last_dir = cur_dir
    cur_dir = os.path.dirname(cur_dir)
    if last_dir == cur_dir:
      raise PathNotFound('Unable to find %s above %s' %
                         (desired_path, start_dir))
    found_path = os.path.join(cur_dir, desired_path)
  # Strip the entire original desired path from the end of the one found
  # and remove a trailing path separator, if present.
  found_path = found_path[:len(found_path) - len(desired_path)]
  if found_path.endswith(os.sep):
    found_path = found_path[:len(found_path) - 1]
  return found_path


def FindUpward(start_dir, *desired_list):
  """Returns a path to the desired directory or file, searching upward.

  Searches start_dir and all its parents looking for the desired directory
  or file, which may be given in one or more path components. Returns the full
  path to the desired object, or raises PathNotFound if it wasn't found.
  """
  parent = FindUpwardParent(start_dir, *desired_list)
  return os.path.join(parent, *desired_list)


def MaybeMakeDirectory(*path):
  """Creates an entire path, if it doesn't already exist."""
  file_path = os.path.join(*path)
  try:
    os.makedirs(file_path)
  except OSError, e:
    # errno.EEXIST is "File exists".  If we see another error, re-raise.
    if e.errno != errno.EEXIST:
      raise
