#
#

# Copyright (C) 2010, 2011, 2012, 2013, 2014 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.

"""Node group related commands"""

# pylint: disable=W0401,W0614
# W0401: Wildcard import ganeti.cli
# W0614: Unused import %s from wildcard import (since we need cli)

from cStringIO import StringIO

from ganeti.cli import *
from ganeti import constants
from ganeti import opcodes
from ganeti import utils
from ganeti import compat
from ganeti.client import base


#: default list of fields for L{ListGroups}
_LIST_DEF_FIELDS = ["name", "node_cnt", "pinst_cnt", "alloc_policy", "ndparams"]

_ENV_OVERRIDE = compat.UniqueFrozenset(["list"])


def AddGroup(opts, args):
  """Add a node group to the cluster.

  @param opts: the command line options selected by the user
  @type args: list
  @param args: a list of length 1 with the name of the group to create
  @rtype: int
  @return: the desired exit code

  """
  ipolicy = CreateIPolicyFromOpts(
    minmax_ispecs=opts.ipolicy_bounds_specs,
    ipolicy_vcpu_ratio=opts.ipolicy_vcpu_ratio,
    ipolicy_spindle_ratio=opts.ipolicy_spindle_ratio,
    ipolicy_disk_templates=opts.ipolicy_disk_templates,
    group_ipolicy=True)

  (group_name,) = args
  diskparams = dict(opts.diskparams)

  if opts.disk_state:
    disk_state = utils.FlatToDict(opts.disk_state)
  else:
    disk_state = {}
  hv_state = dict(opts.hv_state)

  op = opcodes.OpGroupAdd(group_name=group_name, ndparams=opts.ndparams,
                          alloc_policy=opts.alloc_policy,
                          diskparams=diskparams, ipolicy=ipolicy,
                          hv_state=hv_state,
                          disk_state=disk_state)
  return base.GetResult(None, opts, SubmitOrSend(op, opts))


def AssignNodes(opts, args):
  """Assign nodes to a group.

  @param opts: the command line options selected by the user
  @type args: list
  @param args: args[0]: group to assign nodes to; args[1:]: nodes to assign
  @rtype: int
  @return: the desired exit code

  """
  group_name = args[0]
  node_names = args[1:]

  op = opcodes.OpGroupAssignNodes(group_name=group_name, nodes=node_names,
                                  force=opts.force)
  SubmitOrSend(op, opts)


def _FmtDict(data):
  """Format dict data into command-line format.

  @param data: The input dict to be formatted
  @return: The formatted dict

  """
  if not data:
    return "(empty)"

  return utils.CommaJoin(["%s=%s" % (key, value)
                          for key, value in data.items()])


def ListGroups(opts, args):
  """List node groups and their properties.

  @param opts: the command line options selected by the user
  @type args: list
  @param args: groups to list, or empty for all
  @rtype: int
  @return: the desired exit code

  """
  desired_fields = ParseFields(opts.output, _LIST_DEF_FIELDS)
  fmtoverride = {
    "node_list": (",".join, False),
    "pinst_list": (",".join, False),
    "ndparams": (_FmtDict, False),
    }

  cl = GetClient()

  return GenericList(constants.QR_GROUP, desired_fields, args, None,
                     opts.separator, not opts.no_headers,
                     format_override=fmtoverride, verbose=opts.verbose,
                     force_filter=opts.force_filter, cl=cl)


def ListGroupFields(opts, args):
  """List node fields.

  @param opts: the command line options selected by the user
  @type args: list
  @param args: fields to list, or empty for all
  @rtype: int
  @return: the desired exit code

  """
  cl = GetClient()

  return GenericListFields(constants.QR_GROUP, args, opts.separator,
                           not opts.no_headers, cl=cl)


def SetGroupParams(opts, args):
  """Modifies a node group's parameters.

  @param opts: the command line options selected by the user
  @type args: list
  @param args: should contain only one element, the node group name

  @rtype: int
  @return: the desired exit code

  """
  allmods = [opts.ndparams, opts.alloc_policy, opts.diskparams, opts.hv_state,
             opts.disk_state, opts.ipolicy_bounds_specs,
             opts.ipolicy_vcpu_ratio, opts.ipolicy_spindle_ratio,
             opts.diskparams, opts.ipolicy_disk_templates]
  if allmods.count(None) == len(allmods):
    ToStderr("Please give at least one of the parameters.")
    return 1

  if opts.disk_state:
    disk_state = utils.FlatToDict(opts.disk_state)
  else:
    disk_state = {}

  hv_state = dict(opts.hv_state)

  diskparams = dict(opts.diskparams)

  # create ipolicy object
  ipolicy = CreateIPolicyFromOpts(
    minmax_ispecs=opts.ipolicy_bounds_specs,
    ipolicy_disk_templates=opts.ipolicy_disk_templates,
    ipolicy_vcpu_ratio=opts.ipolicy_vcpu_ratio,
    ipolicy_spindle_ratio=opts.ipolicy_spindle_ratio,
    group_ipolicy=True,
    allowed_values=[constants.VALUE_DEFAULT])

  op = opcodes.OpGroupSetParams(group_name=args[0],
                                ndparams=opts.ndparams,
                                alloc_policy=opts.alloc_policy,
                                hv_state=hv_state,
                                disk_state=disk_state,
                                diskparams=diskparams,
                                ipolicy=ipolicy)

  result = SubmitOrSend(op, opts)

  if result:
    ToStdout("Modified node group %s", args[0])
    for param, data in result:
      ToStdout(" - %-5s -> %s", param, data)

  return 0


def RemoveGroup(opts, args):
  """Remove a node group from the cluster.

  @param opts: the command line options selected by the user
  @type args: list
  @param args: a list of length 1 with the name of the group to remove
  @rtype: int
  @return: the desired exit code

  """
  (group_name,) = args
  op = opcodes.OpGroupRemove(group_name=group_name)
  SubmitOrSend(op, opts)


def RenameGroup(opts, args):
  """Rename a node group.

  @param opts: the command line options selected by the user
  @type args: list
  @param args: a list of length 2, [old_name, new_name]
  @rtype: int
  @return: the desired exit code

  """
  group_name, new_name = args
  op = opcodes.OpGroupRename(group_name=group_name, new_name=new_name)
  SubmitOrSend(op, opts)


def EvacuateGroup(opts, args):
  """Evacuate a node group.

  """
  (group_name, ) = args

  cl = GetClient()

  op = opcodes.OpGroupEvacuate(group_name=group_name,
                               iallocator=opts.iallocator,
                               target_groups=opts.to,
                               early_release=opts.early_release,
                               sequential=opts.sequential,
                               force_failover=opts.force_failover)
  result = SubmitOrSend(op, opts, cl=cl)

  # Keep track of submitted jobs
  jex = JobExecutor(cl=cl, opts=opts)

  for (status, job_id) in result[constants.JOB_IDS_KEY]:
    jex.AddJobId(None, status, job_id)

  results = jex.GetResults()
  bad_cnt = len([row for row in results if not row[0]])
  if bad_cnt == 0:
    ToStdout("All instances evacuated successfully.")
    rcode = constants.EXIT_SUCCESS
  else:
    ToStdout("There were %s errors during the evacuation.", bad_cnt)
    rcode = constants.EXIT_FAILURE

  return rcode


def _FormatGroupInfo(group):
  (name, ndparams, custom_ndparams, diskparams, custom_diskparams,
   ipolicy, custom_ipolicy) = group
  return [
    ("Node group", name),
    ("Node parameters", FormatParamsDictInfo(custom_ndparams, ndparams)),
    ("Disk parameters", FormatParamsDictInfo(custom_diskparams, diskparams)),
    ("Instance policy", FormatPolicyInfo(custom_ipolicy, ipolicy, False)),
    ]


def GroupInfo(_, args):
  """Shows info about node group.

  """
  cl = GetClient()
  selected_fields = ["name",
                     "ndparams", "custom_ndparams",
                     "diskparams", "custom_diskparams",
                     "ipolicy", "custom_ipolicy"]
  result = cl.QueryGroups(names=args, fields=selected_fields,
                          use_locking=False)

  PrintGenericInfo([
    _FormatGroupInfo(group) for group in result
    ])


def _GetCreateCommand(group):
  (name, ipolicy) = group
  buf = StringIO()
  buf.write("gnt-group add")
  PrintIPolicyCommand(buf, ipolicy, True)
  buf.write(" ")
  buf.write(name)
  return buf.getvalue()


def ShowCreateCommand(opts, args):
  """Shows the command that can be used to re-create a node group.

  Currently it works only for ipolicy specs.

  """
  cl = GetClient()
  selected_fields = ["name"]
  if opts.include_defaults:
    selected_fields += ["ipolicy"]
  else:
    selected_fields += ["custom_ipolicy"]
  result = cl.QueryGroups(names=args, fields=selected_fields,
                          use_locking=False)

  for group in result:
    ToStdout(_GetCreateCommand(group))


commands = {
  "add": (
    AddGroup, ARGS_ONE_GROUP,
    [DRY_RUN_OPT, ALLOC_POLICY_OPT, NODE_PARAMS_OPT, DISK_PARAMS_OPT,
     HV_STATE_OPT, DISK_STATE_OPT, PRIORITY_OPT]
    + SUBMIT_OPTS + INSTANCE_POLICY_OPTS,
    "<group_name>", "Add a new node group to the cluster"),
  "assign-nodes": (
    AssignNodes, ARGS_ONE_GROUP + ARGS_MANY_NODES,
    [DRY_RUN_OPT, FORCE_OPT, PRIORITY_OPT] + SUBMIT_OPTS,
    "<group_name> <node>...", "Assign nodes to a group"),
  "list": (
    ListGroups, ARGS_MANY_GROUPS,
    [NOHDR_OPT, SEP_OPT, FIELDS_OPT, VERBOSE_OPT, FORCE_FILTER_OPT],
    "[<group_name>...]",
    "Lists the node groups in the cluster. The available fields can be shown"
    " using the \"list-fields\" command (see the man page for details)."
    " The default list is (in order): %s." % utils.CommaJoin(_LIST_DEF_FIELDS)),
  "list-fields": (
    ListGroupFields, [ArgUnknown()], [NOHDR_OPT, SEP_OPT], "[fields...]",
    "Lists all available fields for node groups"),
  "modify": (
    SetGroupParams, ARGS_ONE_GROUP,
    [DRY_RUN_OPT] + SUBMIT_OPTS +
    [ALLOC_POLICY_OPT, NODE_PARAMS_OPT, HV_STATE_OPT, DISK_STATE_OPT,
     DISK_PARAMS_OPT, PRIORITY_OPT]
    + INSTANCE_POLICY_OPTS,
    "<group_name>", "Alters the parameters of a node group"),
  "remove": (
    RemoveGroup, ARGS_ONE_GROUP, [DRY_RUN_OPT, PRIORITY_OPT] + SUBMIT_OPTS,
    "[--dry-run] <group-name>",
    "Remove an (empty) node group from the cluster"),
  "rename": (
    RenameGroup, [ArgGroup(min=2, max=2)],
    [DRY_RUN_OPT] + SUBMIT_OPTS + [PRIORITY_OPT],
    "[--dry-run] <group-name> <new-name>", "Rename a node group"),
  "evacuate": (
    EvacuateGroup, [ArgGroup(min=1, max=1)],
    [TO_GROUP_OPT, IALLOCATOR_OPT, EARLY_RELEASE_OPT, SEQUENTIAL_OPT,
     FORCE_FAILOVER_OPT]
    + SUBMIT_OPTS,
    "[-I <iallocator>] [--to <group>]",
    "Evacuate all instances within a group"),
  "list-tags": (
    ListTags, ARGS_ONE_GROUP, [],
    "<group_name>", "List the tags of the given group"),
  "add-tags": (
    AddTags, [ArgGroup(min=1, max=1), ArgUnknown()],
    [TAG_SRC_OPT, PRIORITY_OPT] + SUBMIT_OPTS,
    "<group_name> tag...", "Add tags to the given group"),
  "remove-tags": (
    RemoveTags, [ArgGroup(min=1, max=1), ArgUnknown()],
    [TAG_SRC_OPT, PRIORITY_OPT] + SUBMIT_OPTS,
    "<group_name> tag...", "Remove tags from the given group"),
  "info": (
    GroupInfo, ARGS_MANY_GROUPS, [], "[<group_name>...]",
    "Show group information"),
  "show-ispecs-cmd": (
    ShowCreateCommand, ARGS_MANY_GROUPS, [INCLUDEDEFAULTS_OPT],
    "[--include-defaults] [<group_name>...]",
    "Show the command line to re-create a group"),
  }


def Main():
  return GenericMain(commands,
                     override={"tag_type": constants.TAG_NODEGROUP},
                     env_override=_ENV_OVERRIDE)
