#
#

# Copyright (C) 2010, 2011, 2012, 2013 Google Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.


"""Module for query operations

How it works:

  - Add field definitions
    - See how L{NODE_FIELDS} is built
    - Each field gets:
      - Query field definition (L{objects.QueryFieldDefinition}, use
        L{_MakeField} for creating), containing:
          - Name, must be lowercase and match L{FIELD_NAME_RE}
          - Title for tables, must not contain whitespace and match
            L{TITLE_RE}
          - Value data type, e.g. L{constants.QFT_NUMBER}
          - Human-readable description, must not end with punctuation or
            contain newlines
      - Data request type, see e.g. C{NQ_*}
      - OR-ed flags, see C{QFF_*}
      - A retrieval function, see L{Query.__init__} for description
    - Pass list of fields through L{_PrepareFieldList} for preparation and
      checks
  - Instantiate L{Query} with prepared field list definition and selected fields
  - Call L{Query.RequestedData} to determine what data to collect/compute
  - Call L{Query.Query} or L{Query.OldStyleQuery} with collected data and use
    result
      - Data container must support iteration using C{__iter__}
      - Items are passed to retrieval functions and can have any format
  - Call L{Query.GetFields} to get list of definitions for selected fields

@attention: Retrieval functions must be idempotent. They can be called multiple
  times, in any order and any number of times.

"""

import logging
import operator
import re

from ganeti import constants
from ganeti import errors
from ganeti import utils
from ganeti import compat
from ganeti import objects
from ganeti import ht
from ganeti import runtime
from ganeti import qlang
from ganeti import jstore

from ganeti.constants import (QFT_UNKNOWN, QFT_TEXT, QFT_BOOL, QFT_NUMBER,
                              QFT_UNIT, QFT_TIMESTAMP, QFT_OTHER,
                              RS_NORMAL, RS_UNKNOWN, RS_NODATA,
                              RS_UNAVAIL, RS_OFFLINE)

(NETQ_CONFIG,
 NETQ_GROUP,
 NETQ_STATS,
 NETQ_INST) = range(300, 304)

# Constants for requesting data from the caller/data provider. Each property
# collected/computed separately by the data provider should have its own to
# only collect the requested data and not more.

(NQ_CONFIG,
 NQ_INST,
 NQ_LIVE,
 NQ_GROUP,
 NQ_OOB) = range(1, 6)

(IQ_CONFIG,
 IQ_LIVE,
 IQ_DISKUSAGE,
 IQ_CONSOLE,
 IQ_NODES,
 IQ_NETWORKS) = range(100, 106)

(LQ_MODE,
 LQ_OWNER,
 LQ_PENDING) = range(10, 13)

(GQ_CONFIG,
 GQ_NODE,
 GQ_INST,
 GQ_DISKPARAMS) = range(200, 204)

(CQ_CONFIG,
 CQ_QUEUE_DRAINED,
 CQ_WATCHER_PAUSE) = range(300, 303)

(JQ_ARCHIVED, ) = range(400, 401)

# Query field flags
QFF_HOSTNAME = 0x01
QFF_IP_ADDRESS = 0x02
QFF_JOB_ID = 0x04
QFF_SPLIT_TIMESTAMP = 0x08
# Next values: 0x10, 0x20, 0x40, 0x80, 0x100, 0x200
QFF_ALL = (QFF_HOSTNAME | QFF_IP_ADDRESS | QFF_JOB_ID | QFF_SPLIT_TIMESTAMP)

FIELD_NAME_RE = re.compile(r"^[a-z0-9/._]+$")
TITLE_RE = re.compile(r"^[^\s]+$")
DOC_RE = re.compile(r"^[A-Z].*[^.,?!]$")

#: Verification function for each field type
_VERIFY_FN = {
  QFT_UNKNOWN: ht.TNone,
  QFT_TEXT: ht.TString,
  QFT_BOOL: ht.TBool,
  QFT_NUMBER: ht.TInt,
  QFT_UNIT: ht.TInt,
  QFT_TIMESTAMP: ht.TNumber,
  QFT_OTHER: lambda _: True,
  }

# Unique objects for special field statuses
_FS_UNKNOWN = object()
_FS_NODATA = object()
_FS_UNAVAIL = object()
_FS_OFFLINE = object()

#: List of all special status
_FS_ALL = compat.UniqueFrozenset([
  _FS_UNKNOWN,
  _FS_NODATA,
  _FS_UNAVAIL,
  _FS_OFFLINE,
  ])

#: VType to QFT mapping
_VTToQFT = {
  # TODO: fix validation of empty strings
  constants.VTYPE_STRING: QFT_OTHER, # since VTYPE_STRINGs can be empty
  constants.VTYPE_MAYBE_STRING: QFT_OTHER,
  constants.VTYPE_BOOL: QFT_BOOL,
  constants.VTYPE_SIZE: QFT_UNIT,
  constants.VTYPE_INT: QFT_NUMBER,
  }

_SERIAL_NO_DOC = "%s object serial number, incremented on each modification"


def _GetUnknownField(ctx, item): # pylint: disable=W0613
  """Gets the contents of an unknown field.

  """
  return _FS_UNKNOWN


def _GetQueryFields(fielddefs, selected):
  """Calculates the internal list of selected fields.

  Unknown fields are returned as L{constants.QFT_UNKNOWN}.

  @type fielddefs: dict
  @param fielddefs: Field definitions
  @type selected: list of strings
  @param selected: List of selected fields

  """
  result = []

  for name in selected:
    try:
      fdef = fielddefs[name]
    except KeyError:
      fdef = (_MakeField(name, name, QFT_UNKNOWN, "Unknown field '%s'" % name),
              None, 0, _GetUnknownField)

    assert len(fdef) == 4

    result.append(fdef)

  return result


def GetAllFields(fielddefs):
  """Extract L{objects.QueryFieldDefinition} from field definitions.

  @rtype: list of L{objects.QueryFieldDefinition}

  """
  return [fdef for (fdef, _, _, _) in fielddefs]


class _FilterHints:
  """Class for filter analytics.

  When filters are used, the user of the L{Query} class usually doesn't know
  exactly which items will be necessary for building the result. It therefore
  has to prepare and compute the input data for potentially returning
  everything.

  There are two ways to optimize this. The first, and simpler, is to assign
  each field a group of data, so that the caller can determine which
  computations are necessary depending on the data groups requested. The list
  of referenced groups must also be computed for fields referenced in the
  filter.

  The second is restricting the items based on a primary key. The primary key
  is usually a unique name (e.g. a node name). This class extracts all
  referenced names from a filter. If it encounters any filter condition which
  disallows such a list to be determined (e.g. a non-equality filter), all
  names will be requested.

  The end-effect is that any operation other than L{qlang.OP_OR} and
  L{qlang.OP_EQUAL} will make the query more expensive.

  """
  def __init__(self, namefield):
    """Initializes this class.

    @type namefield: string
    @param namefield: Field caller is interested in

    """
    self._namefield = namefield

    #: Whether all names need to be requested (e.g. if a non-equality operator
    #: has been used)
    self._allnames = False

    #: Which names to request
    self._names = None

    #: Data kinds referenced by the filter (used by L{Query.RequestedData})
    self._datakinds = set()

  def RequestedNames(self):
    """Returns all requested values.

    Returns C{None} if list of values can't be determined (e.g. encountered
    non-equality operators).

    @rtype: list

    """
    if self._allnames or self._names is None:
      return None

    return utils.UniqueSequence(self._names)

  def ReferencedData(self):
    """Returns all kinds of data referenced by the filter.

    """
    return frozenset(self._datakinds)

  def _NeedAllNames(self):
    """Changes internal state to request all names.

    """
    self._allnames = True
    self._names = None

  def NoteLogicOp(self, op):
    """Called when handling a logic operation.

    @type op: string
    @param op: Operator

    """
    if op != qlang.OP_OR:
      self._NeedAllNames()

  def NoteUnaryOp(self, op, datakind): # pylint: disable=W0613
    """Called when handling an unary operation.

    @type op: string
    @param op: Operator

    """
    if datakind is not None:
      self._datakinds.add(datakind)

    self._NeedAllNames()

  def NoteBinaryOp(self, op, datakind, name, value):
    """Called when handling a binary operation.

    @type op: string
    @param op: Operator
    @type name: string
    @param name: Left-hand side of operator (field name)
    @param value: Right-hand side of operator

    """
    if datakind is not None:
      self._datakinds.add(datakind)

    if self._allnames:
      return

    # If any operator other than equality was used, all names need to be
    # retrieved
    if op == qlang.OP_EQUAL and name == self._namefield:
      if self._names is None:
        self._names = []
      self._names.append(value)
    else:
      self._NeedAllNames()


def _WrapLogicOp(op_fn, sentences, ctx, item):
  """Wrapper for logic operator functions.

  """
  return op_fn(fn(ctx, item) for fn in sentences)


def _WrapUnaryOp(op_fn, inner, ctx, item):
  """Wrapper for unary operator functions.

  """
  return op_fn(inner(ctx, item))


def _WrapBinaryOp(op_fn, retrieval_fn, value, ctx, item):
  """Wrapper for binary operator functions.

  """
  return op_fn(retrieval_fn(ctx, item), value)


def _WrapNot(fn, lhs, rhs):
  """Negates the result of a wrapped function.

  """
  return not fn(lhs, rhs)


def _PrepareRegex(pattern):
  """Compiles a regular expression.

  """
  try:
    return re.compile(pattern)
  except re.error, err:
    raise errors.ParameterError("Invalid regex pattern (%s)" % err)


def _PrepareSplitTimestamp(value):
  """Prepares a value for comparison by L{_MakeSplitTimestampComparison}.

  """
  if ht.TNumber(value):
    return value
  else:
    return utils.MergeTime(value)


def _MakeSplitTimestampComparison(fn):
  """Compares split timestamp values after converting to float.

  """
  return lambda lhs, rhs: fn(utils.MergeTime(lhs), rhs)


def _MakeComparisonChecks(fn):
  """Prepares flag-specific comparisons using a comparison function.

  """
  return [
    (QFF_SPLIT_TIMESTAMP, _MakeSplitTimestampComparison(fn),
     _PrepareSplitTimestamp),
    (QFF_JOB_ID, lambda lhs, rhs: fn(jstore.ParseJobId(lhs), rhs),
     jstore.ParseJobId),
    (None, fn, None),
    ]


class _FilterCompilerHelper:
  """Converts a query filter to a callable usable for filtering.

  """
  # String statement has no effect, pylint: disable=W0105

  #: How deep filters can be nested
  _LEVELS_MAX = 10

  # Unique identifiers for operator groups
  (_OPTYPE_LOGIC,
   _OPTYPE_UNARY,
   _OPTYPE_BINARY) = range(1, 4)

  """Functions for equality checks depending on field flags.

  List of tuples containing flags and a callable receiving the left- and
  right-hand side of the operator. The flags are an OR-ed value of C{QFF_*}
  (e.g. L{QFF_HOSTNAME} or L{QFF_SPLIT_TIMESTAMP}).

  Order matters. The first item with flags will be used. Flags are checked
  using binary AND.

  """
  _EQUALITY_CHECKS = [
    (QFF_HOSTNAME,
     lambda lhs, rhs: utils.MatchNameComponent(rhs, [lhs],
                                               case_sensitive=False),
     None),
    (QFF_SPLIT_TIMESTAMP, _MakeSplitTimestampComparison(operator.eq),
     _PrepareSplitTimestamp),
    (None, operator.eq, None),
    ]

  """Known operators

  Operator as key (C{qlang.OP_*}), value a tuple of operator group
  (C{_OPTYPE_*}) and a group-specific value:

    - C{_OPTYPE_LOGIC}: Callable taking any number of arguments; used by
      L{_HandleLogicOp}
    - C{_OPTYPE_UNARY}: Always C{None}; details handled by L{_HandleUnaryOp}
    - C{_OPTYPE_BINARY}: Callable taking exactly two parameters, the left- and
      right-hand side of the operator, used by L{_HandleBinaryOp}

  """
  _OPS = {
    # Logic operators
    qlang.OP_OR: (_OPTYPE_LOGIC, compat.any),
    qlang.OP_AND: (_OPTYPE_LOGIC, compat.all),

    # Unary operators
    qlang.OP_NOT: (_OPTYPE_UNARY, None),
    qlang.OP_TRUE: (_OPTYPE_UNARY, None),

    # Binary operators
    qlang.OP_EQUAL: (_OPTYPE_BINARY, _EQUALITY_CHECKS),
    qlang.OP_NOT_EQUAL:
      (_OPTYPE_BINARY, [(flags, compat.partial(_WrapNot, fn), valprepfn)
                        for (flags, fn, valprepfn) in _EQUALITY_CHECKS]),
    qlang.OP_LT: (_OPTYPE_BINARY, _MakeComparisonChecks(operator.lt)),
    qlang.OP_LE: (_OPTYPE_BINARY, _MakeComparisonChecks(operator.le)),
    qlang.OP_GT: (_OPTYPE_BINARY, _MakeComparisonChecks(operator.gt)),
    qlang.OP_GE: (_OPTYPE_BINARY, _MakeComparisonChecks(operator.ge)),
    qlang.OP_REGEXP: (_OPTYPE_BINARY, [
      (None, lambda lhs, rhs: rhs.search(lhs), _PrepareRegex),
      ]),
    qlang.OP_CONTAINS: (_OPTYPE_BINARY, [
      (None, operator.contains, None),
      ]),
    }

  def __init__(self, fields):
    """Initializes this class.

    @param fields: Field definitions (return value of L{_PrepareFieldList})

    """
    self._fields = fields
    self._hints = None
    self._op_handler = None

  def __call__(self, hints, qfilter):
    """Converts a query filter into a callable function.

    @type hints: L{_FilterHints} or None
    @param hints: Callbacks doing analysis on filter
    @type qfilter: list
    @param qfilter: Filter structure
    @rtype: callable
    @return: Function receiving context and item as parameters, returning
             boolean as to whether item matches filter

    """
    self._op_handler = {
      self._OPTYPE_LOGIC:
        (self._HandleLogicOp, getattr(hints, "NoteLogicOp", None)),
      self._OPTYPE_UNARY:
        (self._HandleUnaryOp, getattr(hints, "NoteUnaryOp", None)),
      self._OPTYPE_BINARY:
        (self._HandleBinaryOp, getattr(hints, "NoteBinaryOp", None)),
      }

    try:
      filter_fn = self._Compile(qfilter, 0)
    finally:
      self._op_handler = None

    return filter_fn

  def _Compile(self, qfilter, level):
    """Inner function for converting filters.

    Calls the correct handler functions for the top-level operator. This
    function is called recursively (e.g. for logic operators).

    """
    if not (isinstance(qfilter, (list, tuple)) and qfilter):
      raise errors.ParameterError("Invalid filter on level %s" % level)

    # Limit recursion
    if level >= self._LEVELS_MAX:
      raise errors.ParameterError("Only up to %s levels are allowed (filter"
                                  " nested too deep)" % self._LEVELS_MAX)

    # Create copy to be modified
    operands = qfilter[:]
    op = operands.pop(0)

    try:
      (kind, op_data) = self._OPS[op]
    except KeyError:
      raise errors.ParameterError("Unknown operator '%s'" % op)

    (handler, hints_cb) = self._op_handler[kind]

    return handler(hints_cb, level, op, op_data, operands)

  def _LookupField(self, name):
    """Returns a field definition by name.

    """
    try:
      return self._fields[name]
    except KeyError:
      raise errors.ParameterError("Unknown field '%s'" % name)

  def _HandleLogicOp(self, hints_fn, level, op, op_fn, operands):
    """Handles logic operators.

    @type hints_fn: callable
    @param hints_fn: Callback doing some analysis on the filter
    @type level: integer
    @param level: Current depth
    @type op: string
    @param op: Operator
    @type op_fn: callable
    @param op_fn: Function implementing operator
    @type operands: list
    @param operands: List of operands

    """
    if hints_fn:
      hints_fn(op)

    return compat.partial(_WrapLogicOp, op_fn,
                          [self._Compile(op, level + 1) for op in operands])

  def _HandleUnaryOp(self, hints_fn, level, op, op_fn, operands):
    """Handles unary operators.

    @type hints_fn: callable
    @param hints_fn: Callback doing some analysis on the filter
    @type level: integer
    @param level: Current depth
    @type op: string
    @param op: Operator
    @type op_fn: callable
    @param op_fn: Function implementing operator
    @type operands: list
    @param operands: List of operands

    """
    assert op_fn is None

    if len(operands) != 1:
      raise errors.ParameterError("Unary operator '%s' expects exactly one"
                                  " operand" % op)

    if op == qlang.OP_TRUE:
      (_, datakind, _, retrieval_fn) = self._LookupField(operands[0])

      if hints_fn:
        hints_fn(op, datakind)

      op_fn = operator.truth
      arg = retrieval_fn
    elif op == qlang.OP_NOT:
      if hints_fn:
        hints_fn(op, None)

      op_fn = operator.not_
      arg = self._Compile(operands[0], level + 1)
    else:
      raise errors.ProgrammerError("Can't handle operator '%s'" % op)

    return compat.partial(_WrapUnaryOp, op_fn, arg)

  def _HandleBinaryOp(self, hints_fn, level, op, op_data, operands):
    """Handles binary operators.

    @type hints_fn: callable
    @param hints_fn: Callback doing some analysis on the filter
    @type level: integer
    @param level: Current depth
    @type op: string
    @param op: Operator
    @param op_data: Functions implementing operators
    @type operands: list
    @param operands: List of operands

    """
    # Unused arguments, pylint: disable=W0613
    try:
      (name, value) = operands
    except (ValueError, TypeError):
      raise errors.ParameterError("Invalid binary operator, expected exactly"
                                  " two operands")

    (fdef, datakind, field_flags, retrieval_fn) = self._LookupField(name)

    assert fdef.kind != QFT_UNKNOWN

    # TODO: Type conversions?

    verify_fn = _VERIFY_FN[fdef.kind]
    if not verify_fn(value):
      raise errors.ParameterError("Unable to compare field '%s' (type '%s')"
                                  " with '%s', expected %s" %
                                  (name, fdef.kind, value.__class__.__name__,
                                   verify_fn))

    if hints_fn:
      hints_fn(op, datakind, name, value)

    for (fn_flags, fn, valprepfn) in op_data:
      if fn_flags is None or fn_flags & field_flags:
        # Prepare value if necessary (e.g. compile regular expression)
        if valprepfn:
          value = valprepfn(value)

        return compat.partial(_WrapBinaryOp, fn, retrieval_fn, value)

    raise errors.ProgrammerError("Unable to find operator implementation"
                                 " (op '%s', flags %s)" % (op, field_flags))


def _CompileFilter(fields, hints, qfilter):
  """Converts a query filter into a callable function.

  See L{_FilterCompilerHelper} for details.

  @rtype: callable

  """
  return _FilterCompilerHelper(fields)(hints, qfilter)


class Query:
  def __init__(self, fieldlist, selected, qfilter=None, namefield=None):
    """Initializes this class.

    The field definition is a dictionary with the field's name as a key and a
    tuple containing, in order, the field definition object
    (L{objects.QueryFieldDefinition}, the data kind to help calling code
    collect data and a retrieval function. The retrieval function is called
    with two parameters, in order, the data container and the item in container
    (see L{Query.Query}).

    Users of this class can call L{RequestedData} before preparing the data
    container to determine what data is needed.

    @type fieldlist: dictionary
    @param fieldlist: Field definitions
    @type selected: list of strings
    @param selected: List of selected fields

    """
    assert namefield is None or namefield in fieldlist

    self._fields = _GetQueryFields(fieldlist, selected)

    self._filter_fn = None
    self._requested_names = None
    self._filter_datakinds = frozenset()

    if qfilter is not None:
      # Collect requested names if wanted
      if namefield:
        hints = _FilterHints(namefield)
      else:
        hints = None

      # Build filter function
      self._filter_fn = _CompileFilter(fieldlist, hints, qfilter)
      if hints:
        self._requested_names = hints.RequestedNames()
        self._filter_datakinds = hints.ReferencedData()

    if namefield is None:
      self._name_fn = None
    else:
      (_, _, _, self._name_fn) = fieldlist[namefield]

  def RequestedNames(self):
    """Returns all names referenced in the filter.

    If there is no filter or operators are preventing determining the exact
    names, C{None} is returned.

    """
    return self._requested_names

  def RequestedData(self):
    """Gets requested kinds of data.

    @rtype: frozenset

    """
    return (self._filter_datakinds |
            frozenset(datakind for (_, datakind, _, _) in self._fields
                      if datakind is not None))

  def GetFields(self):
    """Returns the list of fields for this query.

    Includes unknown fields.

    @rtype: List of L{objects.QueryFieldDefinition}

    """
    return GetAllFields(self._fields)

  def Query(self, ctx, sort_by_name=True):
    """Execute a query.

    @param ctx: Data container passed to field retrieval functions, must
      support iteration using C{__iter__}
    @type sort_by_name: boolean
    @param sort_by_name: Whether to sort by name or keep the input data's
      ordering

    """
    sort = (self._name_fn and sort_by_name)

    result = []

    for idx, item in enumerate(ctx):
      if not (self._filter_fn is None or self._filter_fn(ctx, item)):
        continue

      row = [_ProcessResult(fn(ctx, item)) for (_, _, _, fn) in self._fields]

      # Verify result
      if __debug__:
        _VerifyResultRow(self._fields, row)

      if sort:
        (status, name) = _ProcessResult(self._name_fn(ctx, item))
        assert status == constants.RS_NORMAL
        # TODO: Are there cases where we wouldn't want to use NiceSort?
        # Answer: if the name field is non-string...
        result.append((utils.NiceSortKey(name), idx, row))
      else:
        result.append(row)

    if not sort:
      return result

    # TODO: Would "heapq" be more efficient than sorting?

    # Sorting in-place instead of using "sorted()"
    result.sort()

    assert not result or (len(result[0]) == 3 and len(result[-1]) == 3)

    return map(operator.itemgetter(2), result)

  def OldStyleQuery(self, ctx, sort_by_name=True):
    """Query with "old" query result format.

    See L{Query.Query} for arguments.

    """
    unknown = set(fdef.name for (fdef, _, _, _) in self._fields
                  if fdef.kind == QFT_UNKNOWN)
    if unknown:
      raise errors.OpPrereqError("Unknown output fields selected: %s" %
                                 (utils.CommaJoin(unknown), ),
                                 errors.ECODE_INVAL)

    return [[value for (_, value) in row]
            for row in self.Query(ctx, sort_by_name=sort_by_name)]


def _ProcessResult(value):
  """Converts result values into externally-visible ones.

  """
  if value is _FS_UNKNOWN:
    return (RS_UNKNOWN, None)
  elif value is _FS_NODATA:
    return (RS_NODATA, None)
  elif value is _FS_UNAVAIL:
    return (RS_UNAVAIL, None)
  elif value is _FS_OFFLINE:
    return (RS_OFFLINE, None)
  else:
    return (RS_NORMAL, value)


def _VerifyResultRow(fields, row):
  """Verifies the contents of a query result row.

  @type fields: list
  @param fields: Field definitions for result
  @type row: list of tuples
  @param row: Row data

  """
  assert len(row) == len(fields)
  errs = []
  for ((status, value), (fdef, _, _, _)) in zip(row, fields):
    if status == RS_NORMAL:
      if not _VERIFY_FN[fdef.kind](value):
        errs.append("normal field %s fails validation (value is %s)" %
                    (fdef.name, value))
    elif value is not None:
      errs.append("abnormal field %s has a non-None value" % fdef.name)
  assert not errs, ("Failed validation: %s in row %s" %
                    (utils.CommaJoin(errs), row))


def _FieldDictKey((fdef, _, flags, fn)):
  """Generates key for field dictionary.

  """
  assert fdef.name and fdef.title, "Name and title are required"
  assert FIELD_NAME_RE.match(fdef.name)
  assert TITLE_RE.match(fdef.title)
  assert (DOC_RE.match(fdef.doc) and len(fdef.doc.splitlines()) == 1 and
          fdef.doc.strip() == fdef.doc), \
         "Invalid description for field '%s'" % fdef.name
  assert callable(fn)
  assert (flags & ~QFF_ALL) == 0, "Unknown flags for field '%s'" % fdef.name

  return fdef.name


def _PrepareFieldList(fields, aliases):
  """Prepares field list for use by L{Query}.

  Converts the list to a dictionary and does some verification.

  @type fields: list of tuples; (L{objects.QueryFieldDefinition}, data
      kind, retrieval function)
  @param fields: List of fields, see L{Query.__init__} for a better
      description
  @type aliases: list of tuples; (alias, target)
  @param aliases: list of tuples containing aliases; for each
      alias/target pair, a duplicate will be created in the field list
  @rtype: dict
  @return: Field dictionary for L{Query}

  """
  if __debug__:
    duplicates = utils.FindDuplicates(fdef.title.lower()
                                      for (fdef, _, _, _) in fields)
    assert not duplicates, "Duplicate title(s) found: %r" % duplicates

  result = utils.SequenceToDict(fields, key=_FieldDictKey)

  for alias, target in aliases:
    assert alias not in result, "Alias %s overrides an existing field" % alias
    assert target in result, "Missing target %s for alias %s" % (target, alias)
    (fdef, k, flags, fn) = result[target]
    fdef = fdef.Copy()
    fdef.name = alias
    result[alias] = (fdef, k, flags, fn)

  assert len(result) == len(fields) + len(aliases)
  assert compat.all(name == fdef.name
                    for (name, (fdef, _, _, _)) in result.items())

  return result


def GetQueryResponse(query, ctx, sort_by_name=True):
  """Prepares the response for a query.

  @type query: L{Query}
  @param ctx: Data container, see L{Query.Query}
  @type sort_by_name: boolean
  @param sort_by_name: Whether to sort by name or keep the input data's
    ordering

  """
  return objects.QueryResponse(data=query.Query(ctx, sort_by_name=sort_by_name),
                               fields=query.GetFields()).ToDict()


def QueryFields(fielddefs, selected):
  """Returns list of available fields.

  @type fielddefs: dict
  @param fielddefs: Field definitions
  @type selected: list of strings
  @param selected: List of selected fields
  @return: List of L{objects.QueryFieldDefinition}

  """
  if selected is None:
    # Client requests all fields, sort by name
    fdefs = utils.NiceSort(GetAllFields(fielddefs.values()),
                           key=operator.attrgetter("name"))
  else:
    # Keep order as requested by client
    fdefs = Query(fielddefs, selected).GetFields()

  return objects.QueryFieldsResponse(fields=fdefs).ToDict()


def _MakeField(name, title, kind, doc):
  """Wrapper for creating L{objects.QueryFieldDefinition} instances.

  @param name: Field name as a regular expression
  @param title: Human-readable title
  @param kind: Field type
  @param doc: Human-readable description

  """
  return objects.QueryFieldDefinition(name=name, title=title, kind=kind,
                                      doc=doc)


def _StaticValueInner(value, ctx, _): # pylint: disable=W0613
  """Returns a static value.

  """
  return value


def _StaticValue(value):
  """Prepares a function to return a static value.

  """
  return compat.partial(_StaticValueInner, value)


def _GetNodeRole(node, master_uuid):
  """Determine node role.

  @type node: L{objects.Node}
  @param node: Node object
  @type master_uuid: string
  @param master_uuid: Master node UUID

  """
  if node.uuid == master_uuid:
    return constants.NR_MASTER
  elif node.master_candidate:
    return constants.NR_MCANDIDATE
  elif node.drained:
    return constants.NR_DRAINED
  elif node.offline:
    return constants.NR_OFFLINE
  else:
    return constants.NR_REGULAR


def _GetItemAttr(attr):
  """Returns a field function to return an attribute of the item.

  @param attr: Attribute name

  """
  getter = operator.attrgetter(attr)
  return lambda _, item: getter(item)


def _GetItemMaybeAttr(attr):
  """Returns a field function to return a not-None attribute of the item.

  If the value is None, then C{_FS_UNAVAIL} will be returned instead.

  @param attr: Attribute name

  """
  def _helper(_, obj):
    val = getattr(obj, attr)
    if val is None:
      return _FS_UNAVAIL
    else:
      return val
  return _helper


def _GetNDParam(name):
  """Return a field function to return an ND parameter out of the context.

  """
  def _helper(ctx, _):
    if ctx.ndparams is None:
      return _FS_UNAVAIL
    else:
      return ctx.ndparams.get(name, None)
  return _helper


def _BuildNDFields(is_group):
  """Builds all the ndparam fields.

  @param is_group: whether this is called at group or node level

  """
  if is_group:
    field_kind = GQ_CONFIG
  else:
    field_kind = NQ_GROUP
  return [(_MakeField("ndp/%s" % name,
                      constants.NDS_PARAMETER_TITLES.get(name,
                                                         "ndp/%s" % name),
                      _VTToQFT[kind], "The \"%s\" node parameter" % name),
           field_kind, 0, _GetNDParam(name))
          for name, kind in constants.NDS_PARAMETER_TYPES.items()]


def _ConvWrapInner(convert, fn, ctx, item):
  """Wrapper for converting values.

  @param convert: Conversion function receiving value as single parameter
  @param fn: Retrieval function

  """
  value = fn(ctx, item)

  # Is the value an abnormal status?
  if compat.any(value is fs for fs in _FS_ALL):
    # Return right away
    return value

  # TODO: Should conversion function also receive context, item or both?
  return convert(value)


def _ConvWrap(convert, fn):
  """Convenience wrapper for L{_ConvWrapInner}.

  @param convert: Conversion function receiving value as single parameter
  @param fn: Retrieval function

  """
  return compat.partial(_ConvWrapInner, convert, fn)


def _GetItemTimestamp(getter):
  """Returns function for getting timestamp of item.

  @type getter: callable
  @param getter: Function to retrieve timestamp attribute

  """
  def fn(_, item):
    """Returns a timestamp of item.

    """
    timestamp = getter(item)
    if timestamp is None:
      # Old configs might not have all timestamps
      return _FS_UNAVAIL
    else:
      return timestamp

  return fn


def _GetItemTimestampFields(datatype):
  """Returns common timestamp fields.

  @param datatype: Field data type for use by L{Query.RequestedData}

  """
  return [
    (_MakeField("ctime", "CTime", QFT_TIMESTAMP, "Creation timestamp"),
     datatype, 0, _GetItemTimestamp(operator.attrgetter("ctime"))),
    (_MakeField("mtime", "MTime", QFT_TIMESTAMP, "Modification timestamp"),
     datatype, 0, _GetItemTimestamp(operator.attrgetter("mtime"))),
    ]


class NodeQueryData:
  """Data container for node data queries.

  """
  def __init__(self, nodes, live_data, master_uuid, node_to_primary,
               node_to_secondary, inst_uuid_to_inst_name, groups, oob_support,
               cluster):
    """Initializes this class.

    """
    self.nodes = nodes
    self.live_data = live_data
    self.master_uuid = master_uuid
    self.node_to_primary = node_to_primary
    self.node_to_secondary = node_to_secondary
    self.inst_uuid_to_inst_name = inst_uuid_to_inst_name
    self.groups = groups
    self.oob_support = oob_support
    self.cluster = cluster

    # Used for individual rows
    self.curlive_data = None
    self.ndparams = None

  def __iter__(self):
    """Iterate over all nodes.

    This function has side-effects and only one instance of the resulting
    generator should be used at a time.

    """
    for node in self.nodes:
      group = self.groups.get(node.group, None)
      if group is None:
        self.ndparams = None
      else:
        self.ndparams = self.cluster.FillND(node, group)
      if self.live_data:
        self.curlive_data = self.live_data.get(node.uuid, None)
      else:
        self.curlive_data = None
      yield node


#: Fields that are direct attributes of an L{objects.Node} object
_NODE_SIMPLE_FIELDS = {
  "drained": ("Drained", QFT_BOOL, 0, "Whether node is drained"),
  "master_candidate": ("MasterC", QFT_BOOL, 0,
                       "Whether node is a master candidate"),
  "master_capable": ("MasterCapable", QFT_BOOL, 0,
                     "Whether node can become a master candidate"),
  "name": ("Node", QFT_TEXT, QFF_HOSTNAME, "Node name"),
  "offline": ("Offline", QFT_BOOL, 0, "Whether node is marked offline"),
  "serial_no": ("SerialNo", QFT_NUMBER, 0, _SERIAL_NO_DOC % "Node"),
  "uuid": ("UUID", QFT_TEXT, 0, "Node UUID"),
  "vm_capable": ("VMCapable", QFT_BOOL, 0, "Whether node can host instances"),
  }


#: Fields requiring talking to the node
# Note that none of these are available for non-vm_capable nodes
_NODE_LIVE_FIELDS = {
  "bootid": ("BootID", QFT_TEXT, "bootid",
             "Random UUID renewed for each system reboot, can be used"
             " for detecting reboots by tracking changes"),
  "cnodes": ("CNodes", QFT_NUMBER, "cpu_nodes",
             "Number of NUMA domains on node (if exported by hypervisor)"),
  "cnos": ("CNOs", QFT_NUMBER, "cpu_dom0",
            "Number of logical processors used by the node OS (dom0 for Xen)"),
  "csockets": ("CSockets", QFT_NUMBER, "cpu_sockets",
               "Number of physical CPU sockets (if exported by hypervisor)"),
  "ctotal": ("CTotal", QFT_NUMBER, "cpu_total", "Number of logical processors"),
  "dfree": ("DFree", QFT_UNIT, "storage_free",
            "Available storage space in storage unit"),
  "dtotal": ("DTotal", QFT_UNIT, "storage_size",
             "Total storage space in storage unit used for instance disk"
             " allocation"),
  "spfree": ("SpFree", QFT_NUMBER, "spindles_free",
             "Available spindles in volume group (exclusive storage only)"),
  "sptotal": ("SpTotal", QFT_NUMBER, "spindles_total",
              "Total spindles in volume group (exclusive storage only)"),
  "mfree": ("MFree", QFT_UNIT, "memory_free",
            "Memory available for instance allocations"),
  "mnode": ("MNode", QFT_UNIT, "memory_dom0",
            "Amount of memory used by node (dom0 for Xen)"),
  "mtotal": ("MTotal", QFT_UNIT, "memory_total",
             "Total amount of memory of physical machine"),
  }


def _GetGroup(cb):
  """Build function for calling another function with an node group.

  @param cb: The callback to be called with the nodegroup

  """
  def fn(ctx, node):
    """Get group data for a node.

    @type ctx: L{NodeQueryData}
    @type inst: L{objects.Node}
    @param inst: Node object

    """
    ng = ctx.groups.get(node.group, None)
    if ng is None:
      # Nodes always have a group, or the configuration is corrupt
      return _FS_UNAVAIL

    return cb(ctx, node, ng)

  return fn


def _GetNodeGroup(ctx, node, ng): # pylint: disable=W0613
  """Returns the name of a node's group.

  @type ctx: L{NodeQueryData}
  @type node: L{objects.Node}
  @param node: Node object
  @type ng: L{objects.NodeGroup}
  @param ng: The node group this node belongs to

  """
  return ng.name


def _GetNodePower(ctx, node):
  """Returns the node powered state

  @type ctx: L{NodeQueryData}
  @type node: L{objects.Node}
  @param node: Node object

  """
  if ctx.oob_support[node.uuid]:
    return node.powered

  return _FS_UNAVAIL


def _GetNdParams(ctx, node, ng):
  """Returns the ndparams for this node.

  @type ctx: L{NodeQueryData}
  @type node: L{objects.Node}
  @param node: Node object
  @type ng: L{objects.NodeGroup}
  @param ng: The node group this node belongs to

  """
  return ctx.cluster.SimpleFillND(ng.FillND(node))


def _GetLiveNodeField(field, kind, ctx, node):
  """Gets the value of a "live" field from L{NodeQueryData}.

  @param field: Live field name
  @param kind: Data kind, one of L{constants.QFT_ALL}
  @type ctx: L{NodeQueryData}
  @type node: L{objects.Node}
  @param node: Node object

  """
  if node.offline:
    return _FS_OFFLINE

  if not node.vm_capable:
    return _FS_UNAVAIL

  if not ctx.curlive_data:
    return _FS_NODATA

  return _GetStatsField(field, kind, ctx.curlive_data)


def _GetStatsField(field, kind, data):
  """Gets a value from live statistics.

  If the value is not found, L{_FS_UNAVAIL} is returned. If the field kind is
  numeric a conversion to integer is attempted. If that fails, L{_FS_UNAVAIL}
  is returned.

  @param field: Live field name
  @param kind: Data kind, one of L{constants.QFT_ALL}
  @type data: dict
  @param data: Statistics

  """
  try:
    value = data[field]
  except KeyError:
    return _FS_UNAVAIL

  if kind == QFT_TEXT:
    return value

  assert kind in (QFT_NUMBER, QFT_UNIT)

  # Try to convert into number
  try:
    return int(value)
  except (ValueError, TypeError):
    logging.exception("Failed to convert node field '%s' (value %r) to int",
                      field, value)
    return _FS_UNAVAIL


def _GetNodeHvState(_, node):
  """Converts node's hypervisor state for query result.

  """
  hv_state = node.hv_state

  if hv_state is None:
    return _FS_UNAVAIL

  return dict((name, value.ToDict()) for (name, value) in hv_state.items())


def _GetNodeDiskState(_, node):
  """Converts node's disk state for query result.

  """
  disk_state = node.disk_state

  if disk_state is None:
    return _FS_UNAVAIL

  return dict((disk_kind, dict((name, value.ToDict())
                               for (name, value) in kind_state.items()))
              for (disk_kind, kind_state) in disk_state.items())


def _BuildNodeFields():
  """Builds list of fields for node queries.

  """
  fields = [
    (_MakeField("pip", "PrimaryIP", QFT_TEXT, "Primary IP address"),
     NQ_CONFIG, 0, _GetItemAttr("primary_ip")),
    (_MakeField("sip", "SecondaryIP", QFT_TEXT, "Secondary IP address"),
     NQ_CONFIG, 0, _GetItemAttr("secondary_ip")),
    (_MakeField("tags", "Tags", QFT_OTHER, "Tags"), NQ_CONFIG, 0,
     lambda ctx, node: list(node.GetTags())),
    (_MakeField("master", "IsMaster", QFT_BOOL, "Whether node is master"),
     NQ_CONFIG, 0, lambda ctx, node: node.uuid == ctx.master_uuid),
    (_MakeField("group", "Group", QFT_TEXT, "Node group"), NQ_GROUP, 0,
     _GetGroup(_GetNodeGroup)),
    (_MakeField("group.uuid", "GroupUUID", QFT_TEXT, "UUID of node group"),
     NQ_CONFIG, 0, _GetItemAttr("group")),
    (_MakeField("powered", "Powered", QFT_BOOL,
                "Whether node is thought to be powered on"),
     NQ_OOB, 0, _GetNodePower),
    (_MakeField("ndparams", "NodeParameters", QFT_OTHER,
                "Merged node parameters"),
     NQ_GROUP, 0, _GetGroup(_GetNdParams)),
    (_MakeField("custom_ndparams", "CustomNodeParameters", QFT_OTHER,
                "Custom node parameters"),
      NQ_GROUP, 0, _GetItemAttr("ndparams")),
    (_MakeField("hv_state", "HypervisorState", QFT_OTHER, "Hypervisor state"),
     NQ_CONFIG, 0, _GetNodeHvState),
    (_MakeField("disk_state", "DiskState", QFT_OTHER, "Disk state"),
     NQ_CONFIG, 0, _GetNodeDiskState),
    ]

  fields.extend(_BuildNDFields(False))

  # Node role
  role_values = (constants.NR_MASTER, constants.NR_MCANDIDATE,
                 constants.NR_REGULAR, constants.NR_DRAINED,
                 constants.NR_OFFLINE)
  role_doc = ("Node role; \"%s\" for master, \"%s\" for master candidate,"
              " \"%s\" for regular, \"%s\" for drained, \"%s\" for offline" %
              role_values)
  fields.append((_MakeField("role", "Role", QFT_TEXT, role_doc), NQ_CONFIG, 0,
                 lambda ctx, node: _GetNodeRole(node, ctx.master_uuid)))
  assert set(role_values) == constants.NR_ALL

  def _GetLength(getter):
    return lambda ctx, node: len(getter(ctx)[node.uuid])

  def _GetList(getter):
    return lambda ctx, node: utils.NiceSort(
                               [ctx.inst_uuid_to_inst_name[uuid]
                                for uuid in getter(ctx)[node.uuid]])

  # Add fields operating on instance lists
  for prefix, titleprefix, docword, getter in \
      [("p", "Pri", "primary", operator.attrgetter("node_to_primary")),
       ("s", "Sec", "secondary", operator.attrgetter("node_to_secondary"))]:
    # TODO: Allow filterting by hostname in list
    fields.extend([
      (_MakeField("%sinst_cnt" % prefix, "%sinst" % prefix.upper(), QFT_NUMBER,
                  "Number of instances with this node as %s" % docword),
       NQ_INST, 0, _GetLength(getter)),
      (_MakeField("%sinst_list" % prefix, "%sInstances" % titleprefix,
                  QFT_OTHER,
                  "List of instances with this node as %s" % docword),
       NQ_INST, 0, _GetList(getter)),
      ])

  # Add simple fields
  fields.extend([
    (_MakeField(name, title, kind, doc), NQ_CONFIG, flags, _GetItemAttr(name))
    for (name, (title, kind, flags, doc)) in _NODE_SIMPLE_FIELDS.items()])

  # Add fields requiring live data
  fields.extend([
    (_MakeField(name, title, kind, doc), NQ_LIVE, 0,
     compat.partial(_GetLiveNodeField, nfield, kind))
    for (name, (title, kind, nfield, doc)) in _NODE_LIVE_FIELDS.items()])

  # Add timestamps
  fields.extend(_GetItemTimestampFields(NQ_CONFIG))

  return _PrepareFieldList(fields, [])


class InstanceQueryData:
  """Data container for instance data queries.

  """
  def __init__(self, instances, cluster, disk_usage, offline_node_uuids,
               bad_node_uuids, live_data, wrongnode_inst, console, nodes,
               groups, networks):
    """Initializes this class.

    @param instances: List of instance objects
    @param cluster: Cluster object
    @type disk_usage: dict; instance UUID as key
    @param disk_usage: Per-instance disk usage
    @type offline_node_uuids: list of strings
    @param offline_node_uuids: List of offline nodes
    @type bad_node_uuids: list of strings
    @param bad_node_uuids: List of faulty nodes
    @type live_data: dict; instance UUID as key
    @param live_data: Per-instance live data
    @type wrongnode_inst: set
    @param wrongnode_inst: Set of instances running on wrong node(s)
    @type console: dict; instance UUID as key
    @param console: Per-instance console information
    @type nodes: dict; node UUID as key
    @param nodes: Node objects
    @type networks: dict; net_uuid as key
    @param networks: Network objects

    """
    assert len(set(bad_node_uuids) & set(offline_node_uuids)) == \
           len(offline_node_uuids), \
           "Offline nodes not included in bad nodes"
    assert not (set(live_data.keys()) & set(bad_node_uuids)), \
           "Found live data for bad or offline nodes"

    self.instances = instances
    self.cluster = cluster
    self.disk_usage = disk_usage
    self.offline_nodes = offline_node_uuids
    self.bad_nodes = bad_node_uuids
    self.live_data = live_data
    self.wrongnode_inst = wrongnode_inst
    self.console = console
    self.nodes = nodes
    self.groups = groups
    self.networks = networks

    # Used for individual rows
    self.inst_hvparams = None
    self.inst_beparams = None
    self.inst_osparams = None
    self.inst_nicparams = None

  def __iter__(self):
    """Iterate over all instances.

    This function has side-effects and only one instance of the resulting
    generator should be used at a time.

    """
    for inst in self.instances:
      self.inst_hvparams = self.cluster.FillHV(inst, skip_globals=True)
      self.inst_beparams = self.cluster.FillBE(inst)
      self.inst_osparams = self.cluster.SimpleFillOS(inst.os, inst.osparams)
      self.inst_nicparams = [self.cluster.SimpleFillNIC(nic.nicparams)
                             for nic in inst.nics]

      yield inst


def _GetInstOperState(ctx, inst):
  """Get instance's operational status.

  @type ctx: L{InstanceQueryData}
  @type inst: L{objects.Instance}
  @param inst: Instance object

  """
  # Can't use RS_OFFLINE here as it would describe the instance to
  # be offline when we actually don't know due to missing data
  if inst.primary_node in ctx.bad_nodes:
    return _FS_NODATA
  else:
    return bool(ctx.live_data.get(inst.uuid))


def _GetInstLiveData(name):
  """Build function for retrieving live data.

  @type name: string
  @param name: Live data field name

  """
  def fn(ctx, inst):
    """Get live data for an instance.

    @type ctx: L{InstanceQueryData}
    @type inst: L{objects.Instance}
    @param inst: Instance object

    """
    if (inst.primary_node in ctx.bad_nodes or
        inst.primary_node in ctx.offline_nodes):
      # Can't use RS_OFFLINE here as it would describe the instance to be
      # offline when we actually don't know due to missing data
      return _FS_NODATA

    if inst.uuid in ctx.live_data:
      data = ctx.live_data[inst.uuid]
      if name in data:
        return data[name]

    return _FS_UNAVAIL

  return fn


def _GetInstStatus(ctx, inst):
  """Get instance status.

  @type ctx: L{InstanceQueryData}
  @type inst: L{objects.Instance}
  @param inst: Instance object

  """
  if inst.primary_node in ctx.offline_nodes:
    return constants.INSTST_NODEOFFLINE

  if inst.primary_node in ctx.bad_nodes:
    return constants.INSTST_NODEDOWN

  if bool(ctx.live_data.get(inst.uuid)):
    if inst.uuid in ctx.wrongnode_inst:
      return constants.INSTST_WRONGNODE
    elif inst.admin_state == constants.ADMINST_UP:
      return constants.INSTST_RUNNING
    else:
      return constants.INSTST_ERRORUP

  if inst.admin_state == constants.ADMINST_UP:
    return constants.INSTST_ERRORDOWN
  elif inst.admin_state == constants.ADMINST_DOWN:
    return constants.INSTST_ADMINDOWN

  return constants.INSTST_ADMINOFFLINE


def _GetInstDisk(index, cb):
  """Build function for calling another function with an instance Disk.

  @type index: int
  @param index: Disk index
  @type cb: callable
  @param cb: Callback

  """
  def fn(ctx, inst):
    """Call helper function with instance Disk.

    @type ctx: L{InstanceQueryData}
    @type inst: L{objects.Instance}
    @param inst: Instance object

    """
    try:
      nic = inst.disks[index]
    except IndexError:
      return _FS_UNAVAIL

    return cb(ctx, index, nic)

  return fn


def _GetInstDiskSize(ctx, _, disk): # pylint: disable=W0613
  """Get a Disk's size.

  @type ctx: L{InstanceQueryData}
  @type disk: L{objects.Disk}
  @param disk: The Disk object

  """
  if disk.size is None:
    return _FS_UNAVAIL
  else:
    return disk.size


def _GetInstDiskSpindles(ctx, _, disk): # pylint: disable=W0613
  """Get a Disk's spindles.

  @type disk: L{objects.Disk}
  @param disk: The Disk object

  """
  if disk.spindles is None:
    return _FS_UNAVAIL
  else:
    return disk.spindles


def _GetInstDeviceName(ctx, _, device): # pylint: disable=W0613
  """Get a Device's Name.

  @type ctx: L{InstanceQueryData}
  @type device: L{objects.NIC} or L{objects.Disk}
  @param device: The NIC or Disk object

  """
  if device.name is None:
    return _FS_UNAVAIL
  else:
    return device.name


def _GetInstDeviceUUID(ctx, _, device): # pylint: disable=W0613
  """Get a Device's UUID.

  @type ctx: L{InstanceQueryData}
  @type device: L{objects.NIC} or L{objects.Disk}
  @param device: The NIC or Disk object

  """
  if device.uuid is None:
    return _FS_UNAVAIL
  else:
    return device.uuid


def _GetInstNic(index, cb):
  """Build function for calling another function with an instance NIC.

  @type index: int
  @param index: NIC index
  @type cb: callable
  @param cb: Callback

  """
  def fn(ctx, inst):
    """Call helper function with instance NIC.

    @type ctx: L{InstanceQueryData}
    @type inst: L{objects.Instance}
    @param inst: Instance object

    """
    try:
      nic = inst.nics[index]
    except IndexError:
      return _FS_UNAVAIL

    return cb(ctx, index, nic)

  return fn


def _GetInstNicNetworkName(ctx, _, nic): # pylint: disable=W0613
  """Get a NIC's Network.

  @type ctx: L{InstanceQueryData}
  @type nic: L{objects.NIC}
  @param nic: NIC object

  """
  if nic.network is None:
    return _FS_UNAVAIL
  else:
    return ctx.networks[nic.network].name


def _GetInstNicNetwork(ctx, _, nic): # pylint: disable=W0613
  """Get a NIC's Network.

  @type ctx: L{InstanceQueryData}
  @type nic: L{objects.NIC}
  @param nic: NIC object

  """
  if nic.network is None:
    return _FS_UNAVAIL
  else:
    return nic.network


def _GetInstNicIp(ctx, _, nic): # pylint: disable=W0613
  """Get a NIC's IP address.

  @type ctx: L{InstanceQueryData}
  @type nic: L{objects.NIC}
  @param nic: NIC object

  """
  if nic.ip is None:
    return _FS_UNAVAIL
  else:
    return nic.ip


def _GetInstNicBridge(ctx, index, _):
  """Get a NIC's bridge.

  @type ctx: L{InstanceQueryData}
  @type index: int
  @param index: NIC index

  """
  assert len(ctx.inst_nicparams) >= index

  nicparams = ctx.inst_nicparams[index]

  if nicparams[constants.NIC_MODE] == constants.NIC_MODE_BRIDGED:
    return nicparams[constants.NIC_LINK]
  else:
    return _FS_UNAVAIL


def _GetInstAllNicNetworkNames(ctx, inst):
  """Get all network names for an instance.

  @type ctx: L{InstanceQueryData}
  @type inst: L{objects.Instance}
  @param inst: Instance object

  """
  result = []

  for nic in inst.nics:
    name = None
    if nic.network:
      name = ctx.networks[nic.network].name
    result.append(name)

  assert len(result) == len(inst.nics)

  return result


def _GetInstAllNicBridges(ctx, inst):
  """Get all network bridges for an instance.

  @type ctx: L{InstanceQueryData}
  @type inst: L{objects.Instance}
  @param inst: Instance object

  """
  assert len(ctx.inst_nicparams) == len(inst.nics)

  result = []

  for nicp in ctx.inst_nicparams:
    if nicp[constants.NIC_MODE] == constants.NIC_MODE_BRIDGED:
      result.append(nicp[constants.NIC_LINK])
    else:
      result.append(None)

  assert len(result) == len(inst.nics)

  return result


def _GetInstNicParam(name):
  """Build function for retrieving a NIC parameter.

  @type name: string
  @param name: Parameter name

  """
  def fn(ctx, index, _):
    """Get a NIC's bridge.

    @type ctx: L{InstanceQueryData}
    @type inst: L{objects.Instance}
    @param inst: Instance object
    @type nic: L{objects.NIC}
    @param nic: NIC object

    """
    assert len(ctx.inst_nicparams) >= index
    return ctx.inst_nicparams[index][name]

  return fn


def _GetInstanceNetworkFields():
  """Get instance fields involving network interfaces.

  @return: Tuple containing list of field definitions used as input for
    L{_PrepareFieldList} and a list of aliases

  """
  nic_mac_fn = lambda ctx, _, nic: nic.mac
  nic_mode_fn = _GetInstNicParam(constants.NIC_MODE)
  nic_link_fn = _GetInstNicParam(constants.NIC_LINK)

  fields = [
    # All NICs
    (_MakeField("nic.count", "NICs", QFT_NUMBER,
                "Number of network interfaces"),
     IQ_CONFIG, 0, lambda ctx, inst: len(inst.nics)),
    (_MakeField("nic.macs", "NIC_MACs", QFT_OTHER,
                "List containing each network interface's MAC address"),
     IQ_CONFIG, 0, lambda ctx, inst: [nic.mac for nic in inst.nics]),
    (_MakeField("nic.ips", "NIC_IPs", QFT_OTHER,
                "List containing each network interface's IP address"),
     IQ_CONFIG, 0, lambda ctx, inst: [nic.ip for nic in inst.nics]),
    (_MakeField("nic.names", "NIC_Names", QFT_OTHER,
                "List containing each network interface's name"),
     IQ_CONFIG, 0, lambda ctx, inst: [nic.name for nic in inst.nics]),
    (_MakeField("nic.uuids", "NIC_UUIDs", QFT_OTHER,
                "List containing each network interface's UUID"),
     IQ_CONFIG, 0, lambda ctx, inst: [nic.uuid for nic in inst.nics]),
    (_MakeField("nic.modes", "NIC_modes", QFT_OTHER,
                "List containing each network interface's mode"), IQ_CONFIG, 0,
     lambda ctx, inst: [nicp[constants.NIC_MODE]
                        for nicp in ctx.inst_nicparams]),
    (_MakeField("nic.links", "NIC_links", QFT_OTHER,
                "List containing each network interface's link"), IQ_CONFIG, 0,
     lambda ctx, inst: [nicp[constants.NIC_LINK]
                        for nicp in ctx.inst_nicparams]),
    (_MakeField("nic.bridges", "NIC_bridges", QFT_OTHER,
                "List containing each network interface's bridge"),
     IQ_CONFIG, 0, _GetInstAllNicBridges),
    (_MakeField("nic.networks", "NIC_networks", QFT_OTHER,
                "List containing each interface's network"), IQ_CONFIG, 0,
     lambda ctx, inst: [nic.network for nic in inst.nics]),
    (_MakeField("nic.networks.names", "NIC_networks_names", QFT_OTHER,
                "List containing each interface's network"),
     IQ_NETWORKS, 0, _GetInstAllNicNetworkNames)
    ]

  # NICs by number
  for i in range(constants.MAX_NICS):
    numtext = utils.FormatOrdinal(i + 1)
    fields.extend([
      (_MakeField("nic.ip/%s" % i, "NicIP/%s" % i, QFT_TEXT,
                  "IP address of %s network interface" % numtext),
       IQ_CONFIG, 0, _GetInstNic(i, _GetInstNicIp)),
      (_MakeField("nic.mac/%s" % i, "NicMAC/%s" % i, QFT_TEXT,
                  "MAC address of %s network interface" % numtext),
       IQ_CONFIG, 0, _GetInstNic(i, nic_mac_fn)),
      (_MakeField("nic.name/%s" % i, "NicName/%s" % i, QFT_TEXT,
                  "Name address of %s network interface" % numtext),
       IQ_CONFIG, 0, _GetInstNic(i, _GetInstDeviceName)),
      (_MakeField("nic.uuid/%s" % i, "NicUUID/%s" % i, QFT_TEXT,
                  "UUID address of %s network interface" % numtext),
       IQ_CONFIG, 0, _GetInstNic(i, _GetInstDeviceUUID)),
      (_MakeField("nic.mode/%s" % i, "NicMode/%s" % i, QFT_TEXT,
                  "Mode of %s network interface" % numtext),
       IQ_CONFIG, 0, _GetInstNic(i, nic_mode_fn)),
      (_MakeField("nic.link/%s" % i, "NicLink/%s" % i, QFT_TEXT,
                  "Link of %s network interface" % numtext),
       IQ_CONFIG, 0, _GetInstNic(i, nic_link_fn)),
      (_MakeField("nic.bridge/%s" % i, "NicBridge/%s" % i, QFT_TEXT,
                  "Bridge of %s network interface" % numtext),
       IQ_CONFIG, 0, _GetInstNic(i, _GetInstNicBridge)),
      (_MakeField("nic.network/%s" % i, "NicNetwork/%s" % i, QFT_TEXT,
                  "Network of %s network interface" % numtext),
       IQ_CONFIG, 0, _GetInstNic(i, _GetInstNicNetwork)),
      (_MakeField("nic.network.name/%s" % i, "NicNetworkName/%s" % i, QFT_TEXT,
                  "Network name of %s network interface" % numtext),
       IQ_NETWORKS, 0, _GetInstNic(i, _GetInstNicNetworkName)),
      ])

  aliases = [
    # Legacy fields for first NIC
    ("ip", "nic.ip/0"),
    ("mac", "nic.mac/0"),
    ("bridge", "nic.bridge/0"),
    ("nic_mode", "nic.mode/0"),
    ("nic_link", "nic.link/0"),
    ("nic_network", "nic.network/0"),
    ]

  return (fields, aliases)


def _GetInstDiskUsage(ctx, inst):
  """Get disk usage for an instance.

  @type ctx: L{InstanceQueryData}
  @type inst: L{objects.Instance}
  @param inst: Instance object

  """
  usage = ctx.disk_usage[inst.uuid]

  if usage is None:
    usage = 0

  return usage


def _GetInstanceConsole(ctx, inst):
  """Get console information for instance.

  @type ctx: L{InstanceQueryData}
  @type inst: L{objects.Instance}
  @param inst: Instance object

  """
  consinfo = ctx.console[inst.uuid]

  if consinfo is None:
    return _FS_UNAVAIL

  return consinfo


def _GetInstanceDiskFields():
  """Get instance fields involving disks.

  @return: List of field definitions used as input for L{_PrepareFieldList}

  """
  fields = [
    (_MakeField("disk_usage", "DiskUsage", QFT_UNIT,
                "Total disk space used by instance on each of its nodes;"
                " this is not the disk size visible to the instance, but"
                " the usage on the node"),
     IQ_DISKUSAGE, 0, _GetInstDiskUsage),
    (_MakeField("disk.count", "Disks", QFT_NUMBER, "Number of disks"),
     IQ_CONFIG, 0, lambda ctx, inst: len(inst.disks)),
    (_MakeField("disk.sizes", "Disk_sizes", QFT_OTHER, "List of disk sizes"),
     IQ_CONFIG, 0, lambda ctx, inst: [disk.size for disk in inst.disks]),
    (_MakeField("disk.spindles", "Disk_spindles", QFT_OTHER,
                "List of disk spindles"),
     IQ_CONFIG, 0, lambda ctx, inst: [disk.spindles for disk in inst.disks]),
    (_MakeField("disk.names", "Disk_names", QFT_OTHER, "List of disk names"),
     IQ_CONFIG, 0, lambda ctx, inst: [disk.name for disk in inst.disks]),
    (_MakeField("disk.uuids", "Disk_UUIDs", QFT_OTHER, "List of disk UUIDs"),
     IQ_CONFIG, 0, lambda ctx, inst: [disk.uuid for disk in inst.disks]),
    ]

  # Disks by number
  for i in range(constants.MAX_DISKS):
    numtext = utils.FormatOrdinal(i + 1)
    fields.extend([
        (_MakeField("disk.size/%s" % i, "Disk/%s" % i, QFT_UNIT,
                    "Disk size of %s disk" % numtext),
         IQ_CONFIG, 0, _GetInstDisk(i, _GetInstDiskSize)),
        (_MakeField("disk.spindles/%s" % i, "DiskSpindles/%s" % i, QFT_NUMBER,
                    "Spindles of %s disk" % numtext),
         IQ_CONFIG, 0, _GetInstDisk(i, _GetInstDiskSpindles)),
        (_MakeField("disk.name/%s" % i, "DiskName/%s" % i, QFT_TEXT,
                    "Name of %s disk" % numtext),
         IQ_CONFIG, 0, _GetInstDisk(i, _GetInstDeviceName)),
        (_MakeField("disk.uuid/%s" % i, "DiskUUID/%s" % i, QFT_TEXT,
                    "UUID of %s disk" % numtext),
         IQ_CONFIG, 0, _GetInstDisk(i, _GetInstDeviceUUID))])

  return fields


def _GetInstanceParameterFields():
  """Get instance fields involving parameters.

  @return: List of field definitions used as input for L{_PrepareFieldList}

  """
  fields = [
    # Filled parameters
    (_MakeField("hvparams", "HypervisorParameters", QFT_OTHER,
                "Hypervisor parameters (merged)"),
     IQ_CONFIG, 0, lambda ctx, _: ctx.inst_hvparams),
    (_MakeField("beparams", "BackendParameters", QFT_OTHER,
                "Backend parameters (merged)"),
     IQ_CONFIG, 0, lambda ctx, _: ctx.inst_beparams),
    (_MakeField("osparams", "OpSysParameters", QFT_OTHER,
                "Operating system parameters (merged)"),
     IQ_CONFIG, 0, lambda ctx, _: ctx.inst_osparams),

    # Unfilled parameters
    (_MakeField("custom_hvparams", "CustomHypervisorParameters", QFT_OTHER,
                "Custom hypervisor parameters"),
     IQ_CONFIG, 0, _GetItemAttr("hvparams")),
    (_MakeField("custom_beparams", "CustomBackendParameters", QFT_OTHER,
                "Custom backend parameters",),
     IQ_CONFIG, 0, _GetItemAttr("beparams")),
    (_MakeField("custom_osparams", "CustomOpSysParameters", QFT_OTHER,
                "Custom operating system parameters",),
     IQ_CONFIG, 0, _GetItemAttr("osparams")),
    (_MakeField("custom_nicparams", "CustomNicParameters", QFT_OTHER,
                "Custom network interface parameters"),
     IQ_CONFIG, 0, lambda ctx, inst: [nic.nicparams for nic in inst.nics]),
    ]

  # HV params
  def _GetInstHvParam(name):
    return lambda ctx, _: ctx.inst_hvparams.get(name, _FS_UNAVAIL)

  fields.extend([
    (_MakeField("hv/%s" % name,
                constants.HVS_PARAMETER_TITLES.get(name, "hv/%s" % name),
                _VTToQFT[kind], "The \"%s\" hypervisor parameter" % name),
     IQ_CONFIG, 0, _GetInstHvParam(name))
    for name, kind in constants.HVS_PARAMETER_TYPES.items()
    if name not in constants.HVC_GLOBALS])

  # BE params
  def _GetInstBeParam(name):
    return lambda ctx, _: ctx.inst_beparams.get(name, None)

  fields.extend([
    (_MakeField("be/%s" % name,
                constants.BES_PARAMETER_TITLES.get(name, "be/%s" % name),
                _VTToQFT[kind], "The \"%s\" backend parameter" % name),
     IQ_CONFIG, 0, _GetInstBeParam(name))
    for name, kind in constants.BES_PARAMETER_TYPES.items()])

  return fields


_INST_SIMPLE_FIELDS = {
  "disk_template": ("Disk_template", QFT_TEXT, 0, "Instance disk template"),
  "hypervisor": ("Hypervisor", QFT_TEXT, 0, "Hypervisor name"),
  "name": ("Instance", QFT_TEXT, QFF_HOSTNAME, "Instance name"),
  # Depending on the hypervisor, the port can be None
  "network_port": ("Network_port", QFT_OTHER, 0,
                   "Instance network port if available (e.g. for VNC console)"),
  "os": ("OS", QFT_TEXT, 0, "Operating system"),
  "serial_no": ("SerialNo", QFT_NUMBER, 0, _SERIAL_NO_DOC % "Instance"),
  "uuid": ("UUID", QFT_TEXT, 0, "Instance UUID"),
  }


def _GetNodeName(ctx, default, node_uuid):
  """Gets node name of a node.

  @type ctx: L{InstanceQueryData}
  @param default: Default value
  @type node_uuid: string
  @param node_uuid: Node UUID

  """
  try:
    node = ctx.nodes[node_uuid]
  except KeyError:
    return default
  else:
    return node.name


def _GetInstNodeGroup(ctx, default, node_uuid):
  """Gets group UUID of an instance node.

  @type ctx: L{InstanceQueryData}
  @param default: Default value
  @type node_uuid: string
  @param node_uuid: Node UUID

  """
  try:
    node = ctx.nodes[node_uuid]
  except KeyError:
    return default
  else:
    return node.group


def _GetInstNodeGroupName(ctx, default, node_uuid):
  """Gets group name of an instance node.

  @type ctx: L{InstanceQueryData}
  @param default: Default value
  @type node_uuid: string
  @param node_uuid: Node UUID

  """
  try:
    node = ctx.nodes[node_uuid]
  except KeyError:
    return default

  try:
    group = ctx.groups[node.group]
  except KeyError:
    return default

  return group.name


def _BuildInstanceFields():
  """Builds list of fields for instance queries.

  """
  fields = [
    (_MakeField("pnode", "Primary_node", QFT_TEXT, "Primary node"),
     IQ_NODES, QFF_HOSTNAME,
     lambda ctx, inst: _GetNodeName(ctx, None, inst.primary_node)),
    (_MakeField("pnode.group", "PrimaryNodeGroup", QFT_TEXT,
                "Primary node's group"),
     IQ_NODES, 0,
     lambda ctx, inst: _GetInstNodeGroupName(ctx, _FS_UNAVAIL,
                                             inst.primary_node)),
    (_MakeField("pnode.group.uuid", "PrimaryNodeGroupUUID", QFT_TEXT,
                "Primary node's group UUID"),
     IQ_NODES, 0,
     lambda ctx, inst: _GetInstNodeGroup(ctx, _FS_UNAVAIL, inst.primary_node)),
    # TODO: Allow filtering by secondary node as hostname
    (_MakeField("snodes", "Secondary_Nodes", QFT_OTHER,
                "Secondary nodes; usually this will just be one node"),
     IQ_NODES, 0,
     lambda ctx, inst: map(compat.partial(_GetNodeName, ctx, None),
                           inst.secondary_nodes)),
    (_MakeField("snodes.group", "SecondaryNodesGroups", QFT_OTHER,
                "Node groups of secondary nodes"),
     IQ_NODES, 0,
     lambda ctx, inst: map(compat.partial(_GetInstNodeGroupName, ctx, None),
                           inst.secondary_nodes)),
    (_MakeField("snodes.group.uuid", "SecondaryNodesGroupsUUID", QFT_OTHER,
                "Node group UUIDs of secondary nodes"),
     IQ_NODES, 0,
     lambda ctx, inst: map(compat.partial(_GetInstNodeGroup, ctx, None),
                           inst.secondary_nodes)),
    (_MakeField("admin_state", "InstanceState", QFT_TEXT,
                "Desired state of instance"),
     IQ_CONFIG, 0, _GetItemAttr("admin_state")),
    (_MakeField("admin_up", "Autostart", QFT_BOOL,
                "Desired state of instance"),
     IQ_CONFIG, 0, lambda ctx, inst: inst.admin_state == constants.ADMINST_UP),
    (_MakeField("disks_active", "DisksActive", QFT_BOOL,
                "Desired state of instance disks"),
     IQ_CONFIG, 0, _GetItemAttr("disks_active")),
    (_MakeField("tags", "Tags", QFT_OTHER, "Tags"), IQ_CONFIG, 0,
     lambda ctx, inst: list(inst.GetTags())),
    (_MakeField("console", "Console", QFT_OTHER,
                "Instance console information"), IQ_CONSOLE, 0,
     _GetInstanceConsole),
    ]

  # Add simple fields
  fields.extend([
    (_MakeField(name, title, kind, doc), IQ_CONFIG, flags, _GetItemAttr(name))
    for (name, (title, kind, flags, doc)) in _INST_SIMPLE_FIELDS.items()])

  # Fields requiring talking to the node
  fields.extend([
    (_MakeField("oper_state", "Running", QFT_BOOL, "Actual state of instance"),
     IQ_LIVE, 0, _GetInstOperState),
    (_MakeField("oper_ram", "Memory", QFT_UNIT,
                "Actual memory usage as seen by hypervisor"),
     IQ_LIVE, 0, _GetInstLiveData("memory")),
    (_MakeField("oper_vcpus", "VCPUs", QFT_NUMBER,
                "Actual number of VCPUs as seen by hypervisor"),
     IQ_LIVE, 0, _GetInstLiveData("vcpus")),
    ])

  # Status field
  status_values = (constants.INSTST_RUNNING, constants.INSTST_ADMINDOWN,
                   constants.INSTST_WRONGNODE, constants.INSTST_ERRORUP,
                   constants.INSTST_ERRORDOWN, constants.INSTST_NODEDOWN,
                   constants.INSTST_NODEOFFLINE, constants.INSTST_ADMINOFFLINE)
  status_doc = ("Instance status; \"%s\" if instance is set to be running"
                " and actually is, \"%s\" if instance is stopped and"
                " is not running, \"%s\" if instance running, but not on its"
                " designated primary node, \"%s\" if instance should be"
                " stopped, but is actually running, \"%s\" if instance should"
                " run, but doesn't, \"%s\" if instance's primary node is down,"
                " \"%s\" if instance's primary node is marked offline,"
                " \"%s\" if instance is offline and does not use dynamic"
                " resources" % status_values)
  fields.append((_MakeField("status", "Status", QFT_TEXT, status_doc),
                 IQ_LIVE, 0, _GetInstStatus))
  assert set(status_values) == constants.INSTST_ALL, \
         "Status documentation mismatch"

  (network_fields, network_aliases) = _GetInstanceNetworkFields()

  fields.extend(network_fields)
  fields.extend(_GetInstanceParameterFields())
  fields.extend(_GetInstanceDiskFields())
  fields.extend(_GetItemTimestampFields(IQ_CONFIG))

  aliases = [
    ("vcpus", "be/vcpus"),
    ("be/memory", "be/maxmem"),
    ("sda_size", "disk.size/0"),
    ("sdb_size", "disk.size/1"),
    ] + network_aliases

  return _PrepareFieldList(fields, aliases)


class LockQueryData:
  """Data container for lock data queries.

  """
  def __init__(self, lockdata):
    """Initializes this class.

    """
    self.lockdata = lockdata

  def __iter__(self):
    """Iterate over all locks.

    """
    return iter(self.lockdata)


def _GetLockOwners(_, data):
  """Returns a sorted list of a lock's current owners.

  """
  (_, _, owners, _) = data

  if owners:
    owners = utils.NiceSort(owners)

  return owners


def _GetLockPending(_, data):
  """Returns a sorted list of a lock's pending acquires.

  """
  (_, _, _, pending) = data

  if pending:
    pending = [(mode, utils.NiceSort(names))
               for (mode, names) in pending]

  return pending


def _BuildLockFields():
  """Builds list of fields for lock queries.

  """
  return _PrepareFieldList([
    # TODO: Lock names are not always hostnames. Should QFF_HOSTNAME be used?
    (_MakeField("name", "Name", QFT_TEXT, "Lock name"), None, 0,
     lambda ctx, (name, mode, owners, pending): name),
    (_MakeField("mode", "Mode", QFT_OTHER,
                "Mode in which the lock is currently acquired"
                " (exclusive or shared)"),
     LQ_MODE, 0, lambda ctx, (name, mode, owners, pending): mode),
    (_MakeField("owner", "Owner", QFT_OTHER, "Current lock owner(s)"),
     LQ_OWNER, 0, _GetLockOwners),
    (_MakeField("pending", "Pending", QFT_OTHER,
                "Threads waiting for the lock"),
     LQ_PENDING, 0, _GetLockPending),
    ], [])


class GroupQueryData:
  """Data container for node group data queries.

  """
  def __init__(self, cluster, groups, group_to_nodes, group_to_instances,
               want_diskparams):
    """Initializes this class.

    @param cluster: Cluster object
    @param groups: List of node group objects
    @type group_to_nodes: dict; group UUID as key
    @param group_to_nodes: Per-group list of nodes
    @type group_to_instances: dict; group UUID as key
    @param group_to_instances: Per-group list of (primary) instances
    @type want_diskparams: bool
    @param want_diskparams: Whether diskparamters should be calculated

    """
    self.groups = groups
    self.group_to_nodes = group_to_nodes
    self.group_to_instances = group_to_instances
    self.cluster = cluster
    self.want_diskparams = want_diskparams

    # Used for individual rows
    self.group_ipolicy = None
    self.ndparams = None
    self.group_dp = None

  def __iter__(self):
    """Iterate over all node groups.

    This function has side-effects and only one instance of the resulting
    generator should be used at a time.

    """
    for group in self.groups:
      self.group_ipolicy = self.cluster.SimpleFillIPolicy(group.ipolicy)
      self.ndparams = self.cluster.SimpleFillND(group.ndparams)
      if self.want_diskparams:
        self.group_dp = self.cluster.SimpleFillDP(group.diskparams)
      else:
        self.group_dp = None
      yield group


_GROUP_SIMPLE_FIELDS = {
  "alloc_policy": ("AllocPolicy", QFT_TEXT, "Allocation policy for group"),
  "name": ("Group", QFT_TEXT, "Group name"),
  "serial_no": ("SerialNo", QFT_NUMBER, _SERIAL_NO_DOC % "Group"),
  "uuid": ("UUID", QFT_TEXT, "Group UUID"),
  }


def _BuildGroupFields():
  """Builds list of fields for node group queries.

  """
  # Add simple fields
  fields = [(_MakeField(name, title, kind, doc), GQ_CONFIG, 0,
             _GetItemAttr(name))
            for (name, (title, kind, doc)) in _GROUP_SIMPLE_FIELDS.items()]

  def _GetLength(getter):
    return lambda ctx, group: len(getter(ctx)[group.uuid])

  def _GetSortedList(getter):
    return lambda ctx, group: utils.NiceSort(getter(ctx)[group.uuid])

  group_to_nodes = operator.attrgetter("group_to_nodes")
  group_to_instances = operator.attrgetter("group_to_instances")

  # Add fields for nodes
  fields.extend([
    (_MakeField("node_cnt", "Nodes", QFT_NUMBER, "Number of nodes"),
     GQ_NODE, 0, _GetLength(group_to_nodes)),
    (_MakeField("node_list", "NodeList", QFT_OTHER, "List of nodes"),
     GQ_NODE, 0, _GetSortedList(group_to_nodes)),
    ])

  # Add fields for instances
  fields.extend([
    (_MakeField("pinst_cnt", "Instances", QFT_NUMBER,
                "Number of primary instances"),
     GQ_INST, 0, _GetLength(group_to_instances)),
    (_MakeField("pinst_list", "InstanceList", QFT_OTHER,
                "List of primary instances"),
     GQ_INST, 0, _GetSortedList(group_to_instances)),
    ])

  # Other fields
  fields.extend([
    (_MakeField("tags", "Tags", QFT_OTHER, "Tags"), GQ_CONFIG, 0,
     lambda ctx, group: list(group.GetTags())),
    (_MakeField("ipolicy", "InstancePolicy", QFT_OTHER,
                "Instance policy limitations (merged)"),
     GQ_CONFIG, 0, lambda ctx, _: ctx.group_ipolicy),
    (_MakeField("custom_ipolicy", "CustomInstancePolicy", QFT_OTHER,
                "Custom instance policy limitations"),
     GQ_CONFIG, 0, _GetItemAttr("ipolicy")),
    (_MakeField("custom_ndparams", "CustomNDParams", QFT_OTHER,
                "Custom node parameters"),
     GQ_CONFIG, 0, _GetItemAttr("ndparams")),
    (_MakeField("ndparams", "NDParams", QFT_OTHER,
                "Node parameters"),
     GQ_CONFIG, 0, lambda ctx, _: ctx.ndparams),
    (_MakeField("diskparams", "DiskParameters", QFT_OTHER,
                "Disk parameters (merged)"),
     GQ_DISKPARAMS, 0, lambda ctx, _: ctx.group_dp),
    (_MakeField("custom_diskparams", "CustomDiskParameters", QFT_OTHER,
                "Custom disk parameters"),
     GQ_CONFIG, 0, _GetItemAttr("diskparams")),
    ])

  # ND parameters
  fields.extend(_BuildNDFields(True))

  fields.extend(_GetItemTimestampFields(GQ_CONFIG))

  return _PrepareFieldList(fields, [])


class OsInfo(objects.ConfigObject):
  __slots__ = [
    "name",
    "valid",
    "hidden",
    "blacklisted",
    "variants",
    "api_versions",
    "parameters",
    "node_status",
    ]


def _BuildOsFields():
  """Builds list of fields for operating system queries.

  """
  fields = [
    (_MakeField("name", "Name", QFT_TEXT, "Operating system name"),
     None, 0, _GetItemAttr("name")),
    (_MakeField("valid", "Valid", QFT_BOOL,
                "Whether operating system definition is valid"),
     None, 0, _GetItemAttr("valid")),
    (_MakeField("hidden", "Hidden", QFT_BOOL,
                "Whether operating system is hidden"),
     None, 0, _GetItemAttr("hidden")),
    (_MakeField("blacklisted", "Blacklisted", QFT_BOOL,
                "Whether operating system is blacklisted"),
     None, 0, _GetItemAttr("blacklisted")),
    (_MakeField("variants", "Variants", QFT_OTHER,
                "Operating system variants"),
     None, 0, _ConvWrap(utils.NiceSort, _GetItemAttr("variants"))),
    (_MakeField("api_versions", "ApiVersions", QFT_OTHER,
                "Operating system API versions"),
     None, 0, _ConvWrap(sorted, _GetItemAttr("api_versions"))),
    (_MakeField("parameters", "Parameters", QFT_OTHER,
                "Operating system parameters"),
     None, 0, _ConvWrap(compat.partial(utils.NiceSort, key=compat.fst),
                        _GetItemAttr("parameters"))),
    (_MakeField("node_status", "NodeStatus", QFT_OTHER,
                "Status from node"),
     None, 0, _GetItemAttr("node_status")),
    ]

  return _PrepareFieldList(fields, [])


class ExtStorageInfo(objects.ConfigObject):
  __slots__ = [
    "name",
    "node_status",
    "nodegroup_status",
    "parameters",
    ]


def _BuildExtStorageFields():
  """Builds list of fields for extstorage provider queries.

  """
  fields = [
    (_MakeField("name", "Name", QFT_TEXT, "ExtStorage provider name"),
     None, 0, _GetItemAttr("name")),
    (_MakeField("node_status", "NodeStatus", QFT_OTHER,
                "Status from node"),
     None, 0, _GetItemAttr("node_status")),
    (_MakeField("nodegroup_status", "NodegroupStatus", QFT_OTHER,
                "Overall Nodegroup status"),
     None, 0, _GetItemAttr("nodegroup_status")),
    (_MakeField("parameters", "Parameters", QFT_OTHER,
                "ExtStorage provider parameters"),
     None, 0, _GetItemAttr("parameters")),
    ]

  return _PrepareFieldList(fields, [])


def _JobUnavailInner(fn, ctx, (job_id, job)): # pylint: disable=W0613
  """Return L{_FS_UNAVAIL} if job is None.

  When listing specifc jobs (e.g. "gnt-job list 1 2 3"), a job may not be
  found, in which case this function converts it to L{_FS_UNAVAIL}.

  """
  if job is None:
    return _FS_UNAVAIL
  else:
    return fn(job)


def _JobUnavail(inner):
  """Wrapper for L{_JobUnavailInner}.

  """
  return compat.partial(_JobUnavailInner, inner)


def _PerJobOpInner(fn, job):
  """Executes a function per opcode in a job.

  """
  return map(fn, job.ops)


def _PerJobOp(fn):
  """Wrapper for L{_PerJobOpInner}.

  """
  return _JobUnavail(compat.partial(_PerJobOpInner, fn))


def _JobTimestampInner(fn, job):
  """Converts unavailable timestamp to L{_FS_UNAVAIL}.

  """
  timestamp = fn(job)

  if timestamp is None:
    return _FS_UNAVAIL
  else:
    return timestamp


def _JobTimestamp(fn):
  """Wrapper for L{_JobTimestampInner}.

  """
  return _JobUnavail(compat.partial(_JobTimestampInner, fn))


def _BuildJobFields():
  """Builds list of fields for job queries.

  """
  fields = [
    (_MakeField("id", "ID", QFT_NUMBER, "Job ID"),
     None, QFF_JOB_ID, lambda _, (job_id, job): job_id),
    (_MakeField("status", "Status", QFT_TEXT, "Job status"),
     None, 0, _JobUnavail(lambda job: job.CalcStatus())),
    (_MakeField("priority", "Priority", QFT_NUMBER,
                ("Current job priority (%s to %s)" %
                 (constants.OP_PRIO_LOWEST, constants.OP_PRIO_HIGHEST))),
     None, 0, _JobUnavail(lambda job: job.CalcPriority())),
    (_MakeField("archived", "Archived", QFT_BOOL, "Whether job is archived"),
     JQ_ARCHIVED, 0, lambda _, (job_id, job): job.archived),
    (_MakeField("ops", "OpCodes", QFT_OTHER, "List of all opcodes"),
     None, 0, _PerJobOp(lambda op: op.input.__getstate__())),
    (_MakeField("opresult", "OpCode_result", QFT_OTHER,
                "List of opcodes results"),
     None, 0, _PerJobOp(operator.attrgetter("result"))),
    (_MakeField("opstatus", "OpCode_status", QFT_OTHER,
                "List of opcodes status"),
     None, 0, _PerJobOp(operator.attrgetter("status"))),
    (_MakeField("oplog", "OpCode_log", QFT_OTHER,
                "List of opcode output logs"),
     None, 0, _PerJobOp(operator.attrgetter("log"))),
    (_MakeField("opstart", "OpCode_start", QFT_OTHER,
                "List of opcode start timestamps (before acquiring locks)"),
     None, 0, _PerJobOp(operator.attrgetter("start_timestamp"))),
    (_MakeField("opexec", "OpCode_exec", QFT_OTHER,
                "List of opcode execution start timestamps (after acquiring"
                " locks)"),
     None, 0, _PerJobOp(operator.attrgetter("exec_timestamp"))),
    (_MakeField("opend", "OpCode_end", QFT_OTHER,
                "List of opcode execution end timestamps"),
     None, 0, _PerJobOp(operator.attrgetter("end_timestamp"))),
    (_MakeField("oppriority", "OpCode_prio", QFT_OTHER,
                "List of opcode priorities"),
     None, 0, _PerJobOp(operator.attrgetter("priority"))),
    (_MakeField("summary", "Summary", QFT_OTHER,
                "List of per-opcode summaries"),
     None, 0, _PerJobOp(lambda op: op.input.Summary())),
    ]

  # Timestamp fields
  for (name, attr, title, desc) in [
    ("received_ts", "received_timestamp", "Received",
     "Timestamp of when job was received"),
    ("start_ts", "start_timestamp", "Start", "Timestamp of job start"),
    ("end_ts", "end_timestamp", "End", "Timestamp of job end"),
    ]:
    getter = operator.attrgetter(attr)
    fields.extend([
      (_MakeField(name, title, QFT_OTHER,
                  "%s (tuple containing seconds and microseconds)" % desc),
       None, QFF_SPLIT_TIMESTAMP, _JobTimestamp(getter)),
      ])

  return _PrepareFieldList(fields, [])


def _GetExportName(_, (node_name, expname)): # pylint: disable=W0613
  """Returns an export name if available.

  """
  if expname is None:
    return _FS_NODATA
  else:
    return expname


def _BuildExportFields():
  """Builds list of fields for exports.

  """
  fields = [
    (_MakeField("node", "Node", QFT_TEXT, "Node name"),
     None, QFF_HOSTNAME, lambda _, (node_name, expname): node_name),
    (_MakeField("export", "Export", QFT_TEXT, "Export name"),
     None, 0, _GetExportName),
    ]

  return _PrepareFieldList(fields, [])


_CLUSTER_VERSION_FIELDS = {
  "software_version": ("SoftwareVersion", QFT_TEXT, constants.RELEASE_VERSION,
                       "Software version"),
  "protocol_version": ("ProtocolVersion", QFT_NUMBER,
                       constants.PROTOCOL_VERSION,
                       "RPC protocol version"),
  "config_version": ("ConfigVersion", QFT_NUMBER, constants.CONFIG_VERSION,
                     "Configuration format version"),
  "os_api_version": ("OsApiVersion", QFT_NUMBER, max(constants.OS_API_VERSIONS),
                     "API version for OS template scripts"),
  "export_version": ("ExportVersion", QFT_NUMBER, constants.EXPORT_VERSION,
                     "Import/export file format version"),
  "vcs_version": ("VCSVersion", QFT_TEXT, constants.VCS_VERSION,
                     "VCS version"),
  }


_CLUSTER_SIMPLE_FIELDS = {
  "cluster_name": ("Name", QFT_TEXT, QFF_HOSTNAME, "Cluster name"),
  "volume_group_name": ("VgName", QFT_TEXT, 0, "LVM volume group name"),
  }


class ClusterQueryData:
  def __init__(self, cluster, nodes, drain_flag, watcher_pause):
    """Initializes this class.

    @type cluster: L{objects.Cluster}
    @param cluster: Instance of cluster object
    @type nodes: dict; node UUID as key
    @param nodes: Node objects
    @type drain_flag: bool
    @param drain_flag: Whether job queue is drained
    @type watcher_pause: number
    @param watcher_pause: Until when watcher is paused (Unix timestamp)

    """
    self._cluster = cluster
    self.nodes = nodes
    self.drain_flag = drain_flag
    self.watcher_pause = watcher_pause

  def __iter__(self):
    return iter([self._cluster])


def _ClusterWatcherPause(ctx, _):
  """Returns until when watcher is paused (if available).

  """
  if ctx.watcher_pause is None:
    return _FS_UNAVAIL
  else:
    return ctx.watcher_pause


def _BuildClusterFields():
  """Builds list of fields for cluster information.

  """
  fields = [
    (_MakeField("tags", "Tags", QFT_OTHER, "Tags"), CQ_CONFIG, 0,
     lambda ctx, cluster: list(cluster.GetTags())),
    (_MakeField("architecture", "ArchInfo", QFT_OTHER,
                "Architecture information"), None, 0,
     lambda ctx, _: runtime.GetArchInfo()),
    (_MakeField("drain_flag", "QueueDrained", QFT_BOOL,
                "Flag whether job queue is drained"), CQ_QUEUE_DRAINED, 0,
     lambda ctx, _: ctx.drain_flag),
    (_MakeField("watcher_pause", "WatcherPause", QFT_TIMESTAMP,
                "Until when watcher is paused"), CQ_WATCHER_PAUSE, 0,
     _ClusterWatcherPause),
    (_MakeField("master_node", "Master", QFT_TEXT, "Master node name"),
     CQ_CONFIG, QFF_HOSTNAME,
     lambda ctx, cluster: _GetNodeName(ctx, None, cluster.master_node)),
    ]

  # Simple fields
  fields.extend([
    (_MakeField(name, title, kind, doc), CQ_CONFIG, flags, _GetItemAttr(name))
    for (name, (title, kind, flags, doc)) in _CLUSTER_SIMPLE_FIELDS.items()
    ],)

  # Version fields
  fields.extend([
    (_MakeField(name, title, kind, doc), None, 0, _StaticValue(value))
    for (name, (title, kind, value, doc)) in _CLUSTER_VERSION_FIELDS.items()])

  # Add timestamps
  fields.extend(_GetItemTimestampFields(CQ_CONFIG))

  return _PrepareFieldList(fields, [
    ("name", "cluster_name")])


class NetworkQueryData:
  """Data container for network data queries.

  """
  def __init__(self, networks, network_to_groups,
               network_to_instances, stats):
    """Initializes this class.

    @param networks: List of network objects
    @type network_to_groups: dict; network UUID as key
    @param network_to_groups: Per-network list of groups
    @type network_to_instances: dict; network UUID as key
    @param network_to_instances: Per-network list of instances
    @type stats: dict; network UUID as key
    @param stats: Per-network usage statistics

    """
    self.networks = networks
    self.network_to_groups = network_to_groups
    self.network_to_instances = network_to_instances
    self.stats = stats

  def __iter__(self):
    """Iterate over all networks.

    """
    for net in self.networks:
      if self.stats:
        self.curstats = self.stats.get(net.uuid, None)
      else:
        self.curstats = None
      yield net


_NETWORK_SIMPLE_FIELDS = {
  "name": ("Network", QFT_TEXT, 0, "Name"),
  "network": ("Subnet", QFT_TEXT, 0, "IPv4 subnet"),
  "gateway": ("Gateway", QFT_OTHER, 0, "IPv4 gateway"),
  "network6": ("IPv6Subnet", QFT_OTHER, 0, "IPv6 subnet"),
  "gateway6": ("IPv6Gateway", QFT_OTHER, 0, "IPv6 gateway"),
  "mac_prefix": ("MacPrefix", QFT_OTHER, 0, "MAC address prefix"),
  "serial_no": ("SerialNo", QFT_NUMBER, 0, _SERIAL_NO_DOC % "Network"),
  "uuid": ("UUID", QFT_TEXT, 0, "Network UUID"),
  }


_NETWORK_STATS_FIELDS = {
  "free_count": ("FreeCount", QFT_NUMBER, 0, "Number of available addresses"),
  "reserved_count":
    ("ReservedCount", QFT_NUMBER, 0, "Number of reserved addresses"),
  "map": ("Map", QFT_TEXT, 0, "Actual mapping"),
  "external_reservations":
    ("ExternalReservations", QFT_TEXT, 0, "External reservations"),
  }


def _GetNetworkStatsField(field, kind, ctx, _):
  """Gets the value of a "stats" field from L{NetworkQueryData}.

  @param field: Field name
  @param kind: Data kind, one of L{constants.QFT_ALL}
  @type ctx: L{NetworkQueryData}

  """
  return _GetStatsField(field, kind, ctx.curstats)


def _BuildNetworkFields():
  """Builds list of fields for network queries.

  """
  fields = [
    (_MakeField("tags", "Tags", QFT_OTHER, "Tags"), IQ_CONFIG, 0,
     lambda ctx, inst: list(inst.GetTags())),
    ]

  # Add simple fields
  fields.extend([
    (_MakeField(name, title, kind, doc),
     NETQ_CONFIG, 0, _GetItemMaybeAttr(name))
     for (name, (title, kind, _, doc)) in _NETWORK_SIMPLE_FIELDS.items()])

  def _GetLength(getter):
    return lambda ctx, network: len(getter(ctx)[network.uuid])

  def _GetSortedList(getter):
    return lambda ctx, network: utils.NiceSort(getter(ctx)[network.uuid])

  network_to_groups = operator.attrgetter("network_to_groups")
  network_to_instances = operator.attrgetter("network_to_instances")

  # Add fields for node groups
  fields.extend([
    (_MakeField("group_cnt", "NodeGroups", QFT_NUMBER, "Number of nodegroups"),
     NETQ_GROUP, 0, _GetLength(network_to_groups)),
    (_MakeField("group_list", "GroupList", QFT_OTHER,
     "List of nodegroups (group name, NIC mode, NIC link)"),
     NETQ_GROUP, 0, lambda ctx, network: network_to_groups(ctx)[network.uuid]),
    ])

  # Add fields for instances
  fields.extend([
    (_MakeField("inst_cnt", "Instances", QFT_NUMBER, "Number of instances"),
     NETQ_INST, 0, _GetLength(network_to_instances)),
    (_MakeField("inst_list", "InstanceList", QFT_OTHER, "List of instances"),
     NETQ_INST, 0, _GetSortedList(network_to_instances)),
    ])

  # Add fields for usage statistics
  fields.extend([
    (_MakeField(name, title, kind, doc), NETQ_STATS, 0,
     compat.partial(_GetNetworkStatsField, name, kind))
    for (name, (title, kind, _, doc)) in _NETWORK_STATS_FIELDS.items()])

  # Add timestamps
  fields.extend(_GetItemTimestampFields(IQ_NETWORKS))

  return _PrepareFieldList(fields, [])

#: Fields for cluster information
CLUSTER_FIELDS = _BuildClusterFields()

#: Fields available for node queries
NODE_FIELDS = _BuildNodeFields()

#: Fields available for instance queries
INSTANCE_FIELDS = _BuildInstanceFields()

#: Fields available for lock queries
LOCK_FIELDS = _BuildLockFields()

#: Fields available for node group queries
GROUP_FIELDS = _BuildGroupFields()

#: Fields available for operating system queries
OS_FIELDS = _BuildOsFields()

#: Fields available for extstorage provider queries
EXTSTORAGE_FIELDS = _BuildExtStorageFields()

#: Fields available for job queries
JOB_FIELDS = _BuildJobFields()

#: Fields available for exports
EXPORT_FIELDS = _BuildExportFields()

#: Fields available for network queries
NETWORK_FIELDS = _BuildNetworkFields()

#: All available resources
ALL_FIELDS = {
  constants.QR_CLUSTER: CLUSTER_FIELDS,
  constants.QR_INSTANCE: INSTANCE_FIELDS,
  constants.QR_NODE: NODE_FIELDS,
  constants.QR_LOCK: LOCK_FIELDS,
  constants.QR_GROUP: GROUP_FIELDS,
  constants.QR_OS: OS_FIELDS,
  constants.QR_EXTSTORAGE: EXTSTORAGE_FIELDS,
  constants.QR_JOB: JOB_FIELDS,
  constants.QR_EXPORT: EXPORT_FIELDS,
  constants.QR_NETWORK: NETWORK_FIELDS,
  }

#: All available field lists
ALL_FIELD_LISTS = ALL_FIELDS.values()
