# Copyright 2014 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.
from cStringIO import StringIO


# Can be reproduced with `git mktree --batch <<<''`
EMPTY_TREE = '4b825dc642cb6eb9a060e54bf8d69288fbee4904'

class _Invalid(object):
  def __call__(self, *_args, **_kwargs):
    return self

  def __getattr__(self, _key):
    return self

  def __eq__(self, _other):
    return False

  def __ne__(self, _other):  # pylint: disable=R0201
    return True

  def __repr__(self):
    return 'git2.INVALID'

INVALID = _Invalid()


class CalledProcessError(Exception):
  """Almost like subprocess.CalledProcessError, but also captures stderr,
  and gives prettier error messages.
  """
  def __init__(self, returncode, cmd, stdout, stderr):
    super(CalledProcessError, self).__init__()
    self.returncode = returncode
    self.cmd = cmd
    self.stdout = stdout
    self.stderr = stderr

  def __str__(self):
    msg = StringIO()

    suffix = ':' if self.stderr or self.stdout else '.'
    print >> msg, (
        "Command %r returned non-zero exit status %d%s"
        % (self.cmd, self.returncode, suffix)
    )

    def indent_data(banner, data):
      print >> msg, banner, '=' * 40
      msg.writelines('  ' + l for l in data.splitlines(True))

    if self.stdout:
      indent_data('STDOUT', self.stdout)

    if self.stderr:
      if self.stdout:
        print >> msg
      indent_data('STDERR', self.stderr)

    r = msg.getvalue()
    if r[-1] != '\n':
      r += '\n'
    return r
