#
#

# Copyright (C) 2006, 2007, 2010, 2013 Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""OS scripts related commands"""

# pylint: disable=W0401,W0613,W0614,C0103
# W0401: Wildcard import ganeti.cli
# W0613: Unused argument, since all functions follow the same API
# W0614: Unused import %s from wildcard import (since we need cli)
# C0103: Invalid name gnt-os

from ganeti.cli import *
from ganeti import constants
from ganeti import opcodes
from ganeti import utils


def ListOS(opts, args):
  """List the valid OSes in the cluster.

  @param opts: the command line options selected by the user
  @type args: list
  @param args: should be an empty list
  @rtype: int
  @return: the desired exit code

  """
  op = opcodes.OpOsDiagnose(output_fields=["name", "variants"],
                            names=[])
  result = SubmitOpCode(op, opts=opts)

  if not opts.no_headers:
    headers = {"name": "Name"}
  else:
    headers = None

  os_names = []
  for (name, variants) in result:
    os_names.extend([[n] for n in CalculateOSNames(name, variants)])

  data = GenerateTable(separator=None, headers=headers, fields=["name"],
                       data=os_names, units=None)

  for line in data:
    ToStdout(line)

  return 0


def ShowOSInfo(opts, args):
  """List detailed information about OSes in the cluster.

  @param opts: the command line options selected by the user
  @type args: list
  @param args: should be an empty list
  @rtype: int
  @return: the desired exit code

  """
  op = opcodes.OpOsDiagnose(output_fields=["name", "valid", "variants",
                                           "parameters", "api_versions",
                                           "blacklisted", "hidden", "os_hvp",
                                           "osparams", "trusted"],
                            names=[])
  result = SubmitOpCode(op, opts=opts)

  if result is None:
    ToStderr("Can't get the OS list")
    return 1

  do_filter = bool(args)

  total_os_hvp = {}
  total_osparams = {}

  for (name, valid, variants, parameters, api_versions, blk, hid, os_hvp,
       osparams, trusted) in result:
    total_os_hvp.update(os_hvp)
    total_osparams.update(osparams)
    if do_filter:
      if name not in args:
        continue
      else:
        args.remove(name)
    ToStdout("%s:", name)
    ToStdout("  - valid: %s", valid)
    ToStdout("  - hidden: %s", hid)
    ToStdout("  - blacklisted: %s", blk)
    if valid:
      ToStdout("  - API versions:")
      for version in sorted(api_versions):
        ToStdout("    - %s", version)
      ToStdout("  - variants:")
      for vname in variants:
        ToStdout("    - %s", vname)
      ToStdout("  - parameters:")
      for pname, pdesc in parameters:
        ToStdout("    - %s: %s", pname, pdesc)
    ToStdout("  - trusted: %s", trusted)
    ToStdout("")

  if args:
    all_names = total_os_hvp.keys() + total_osparams.keys()
    for name in args:
      if not name in all_names:
        ToStdout("%s: ", name)
      else:
        info = [
          (name, [
            ("OS-specific hypervisor parameters", total_os_hvp.get(name, {})),
            ("OS parameters", total_osparams.get(name, {})),
            ]),
          ]
        PrintGenericInfo(info)
      ToStdout("")

  return 0


def _OsStatus(status, diagnose):
  """Beautifier function for OS status.

  @type status: boolean
  @param status: is the OS valid
  @type diagnose: string
  @param diagnose: the error message for invalid OSes
  @rtype: string
  @return: a formatted status

  """
  if status:
    return "valid"
  else:
    return "invalid - %s" % diagnose


def DiagnoseOS(opts, args):
  """Analyse all OSes on this cluster.

  @param opts: the command line options selected by the user
  @type args: list
  @param args: should be an empty list
  @rtype: int
  @return: the desired exit code

  """
  op = opcodes.OpOsDiagnose(output_fields=["name", "valid", "variants",
                                           "node_status", "hidden",
                                           "blacklisted"], names=[])
  result = SubmitOpCode(op, opts=opts)

  if result is None:
    ToStderr("Can't get the OS list")
    return 1

  has_bad = False

  for os_name, _, os_variants, node_data, hid, blk in result:
    nodes_valid = {}
    nodes_bad = {}
    nodes_hidden = {}
    for node_name, node_info in node_data.iteritems():
      nodes_hidden[node_name] = []
      if node_info: # at least one entry in the per-node list
        (fo_path, fo_status, fo_msg, fo_variants,
         fo_params, fo_api, fo_trusted) = node_info.pop(0)
        fo_msg = "%s (path: %s)" % (_OsStatus(fo_status, fo_msg), fo_path)
        if fo_api:
          max_os_api = max(fo_api)
          fo_msg += " [API versions: %s]" % utils.CommaJoin(fo_api)
        else:
          max_os_api = 0
          fo_msg += " [no API versions declared]"

        if max_os_api >= constants.OS_API_V15:
          if fo_variants:
            fo_msg += " [variants: %s]" % utils.CommaJoin(fo_variants)
          else:
            fo_msg += " [no variants]"
        if max_os_api >= constants.OS_API_V20:
          if fo_params:
            fo_msg += (" [parameters: %s]" %
                       utils.CommaJoin([v[0] for v in fo_params]))
          else:
            fo_msg += " [no parameters]"
        if fo_trusted:
          fo_msg += " [trusted]"
        else:
          fo_msg += " [untrusted]"
        if fo_status:
          nodes_valid[node_name] = fo_msg
        else:
          nodes_bad[node_name] = fo_msg
        for hpath, hstatus, hmsg, _, _, _ in node_info:
          nodes_hidden[node_name].append("    [hidden] path: %s, status: %s" %
                                         (hpath, _OsStatus(hstatus, hmsg)))
      else:
        nodes_bad[node_name] = "OS not found"

    # TODO: Shouldn't the global status be calculated by the LU?
    if nodes_valid and not nodes_bad:
      status = "valid"
    elif not nodes_valid and nodes_bad:
      status = "invalid"
      has_bad = True
    else:
      status = "partial valid"
      has_bad = True

    def _OutputPerNodeOSStatus(msg_map):
      map_k = utils.NiceSort(msg_map.keys())
      for node_name in map_k:
        ToStdout("  Node: %s, status: %s", node_name, msg_map[node_name])
        for msg in nodes_hidden[node_name]:
          ToStdout(msg)

    st_msg = "OS: %s [global status: %s]" % (os_name, status)
    if hid:
      st_msg += " [hidden]"
    if blk:
      st_msg += " [blacklisted]"
    ToStdout(st_msg)
    if os_variants:
      ToStdout("  Variants: [%s]" % utils.CommaJoin(os_variants))
    _OutputPerNodeOSStatus(nodes_valid)
    _OutputPerNodeOSStatus(nodes_bad)
    ToStdout("")

  return int(has_bad)


def ModifyOS(opts, args):
  """Modify OS parameters for one OS.

  @param opts: the command line options selected by the user
  @type args: list
  @param args: should be a list with one entry
  @rtype: int
  @return: the desired exit code

  """
  # We have to disable pylint for this assignment because of a Pylint bug:
  # Even though there is no `os` in scope, it claims
  #   Redefining name 'os' from outer scope
  # It is supposed to come from `from ganeti.cli import *`, but that doesn't
  # export `os` since it has `__all__` set.
  os = args[0]  # pylint: disable=W0621

  if opts.hvparams:
    os_hvp = {os: dict(opts.hvparams)}
  else:
    os_hvp = None

  if opts.osparams:
    osp = {os: opts.osparams}
  else:
    osp = None

  if opts.osparams_private:
    osp_private = {os: opts.osparams_private}
  else:
    osp_private = None

  if opts.hidden is not None:
    if opts.hidden:
      ohid = [(constants.DDM_ADD, os)]
    else:
      ohid = [(constants.DDM_REMOVE, os)]
  else:
    ohid = None

  if opts.blacklisted is not None:
    if opts.blacklisted:
      oblk = [(constants.DDM_ADD, os)]
    else:
      oblk = [(constants.DDM_REMOVE, os)]
  else:
    oblk = None

  if not (os_hvp or osp or osp_private or ohid or oblk):
    ToStderr("At least one of OS parameters or hypervisor parameters"
             " must be passed")
    return 1

  op = opcodes.OpClusterSetParams(os_hvp=os_hvp,
                                  osparams=osp,
                                  osparams_private_cluster=osp_private,
                                  hidden_os=ohid,
                                  blacklisted_os=oblk)
  SubmitOrSend(op, opts)

  return 0


commands = {
  "list": (
    ListOS, ARGS_NONE, [NOHDR_OPT, PRIORITY_OPT],
    "", "Lists all valid operating systems on the cluster"),
  "diagnose": (
    DiagnoseOS, ARGS_NONE, [PRIORITY_OPT],
    "", "Diagnose all operating systems"),
  "info": (
    ShowOSInfo, [ArgOs()], [PRIORITY_OPT],
    "", "Show detailed information about "
    "operating systems"),
  "modify": (
    ModifyOS, ARGS_ONE_OS,
    [HVLIST_OPT, OSPARAMS_OPT, OSPARAMS_PRIVATE_OPT,
     DRY_RUN_OPT, PRIORITY_OPT, HID_OS_OPT, BLK_OS_OPT] + SUBMIT_OPTS,
    "", "Modify the OS parameters"),
  }

#: dictionary with aliases for commands
aliases = {
  "show": "info",
  }


def Main():
  return GenericMain(commands, aliases=aliases)
