#!/usr/bin/python
#

# Copyright (C) 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.


"""Tool to query the cluster configuration over RConfD

"""
# tool name shouldn't follow module naming.
# pylint: disable=C0103


import optparse
import sys

from ganeti import constants
from ganeti import cli
from ganeti import utils
from ganeti import pathutils

from ganeti.confd import client as confd_client

USAGE = ("\tquery-config [--addr=host] [--hmac=key] QUERY [QUERY...]")

OPTIONS = [
  cli.cli_option("--hmac", dest="hmac", default=None,
                 help="Specify HMAC key instead of reading"
                 " it from the filesystem",
                 metavar="<KEY>"),
  cli.cli_option("-a", "--address", dest="mc", default="127.0.0.1",
                 help="Server IP to query (default: 127.0.0.1)",
                 metavar="<ADDRESS>")
  ]


def Err(msg, exit_code=1):
  """Simple error logging that prints to stderr.

  """
  sys.stderr.write(msg + "\n")
  sys.stderr.flush()
  sys.exit(exit_code)


def Usage():
  """Shows program usage information and exits the program.

  """

  print >> sys.stderr, "Usage:"
  print >> sys.stderr, USAGE
  sys.exit(2)


class QueryClient(object):
  """Confd client for querying the configuration JSON.

  """
  def __init__(self):
    """Constructor.

    """
    self.opts = None
    self.cluster_master = None
    self.instance_ips = None
    self.is_timing = False
    self.ParseOptions()

  def ParseOptions(self):
    """Parses the command line options.

    In case of command line errors, it will show the usage and exit the
    program.

    @return: a tuple (options, args), as returned by OptionParser.parse_args

    """
    parser = optparse.OptionParser(usage="\n%s" % USAGE,
                                   version=("%%prog (ganeti) %s" %
                                            constants.RELEASE_VERSION),
                                   option_list=OPTIONS)

    options, args = parser.parse_args()
    if args == []:
      Usage()

    self.paths = args

    if options.hmac is None:
      options.hmac = utils.ReadFile(pathutils.CONFD_HMAC_KEY)

    self.hmac_key = options.hmac

    self.mc_list = [options.mc]

    self.opts = options

  def Run(self):
    self.store_callback = confd_client.StoreResultCallback()

    self.confd_client = confd_client.ConfdClient(
        self.hmac_key, self.mc_list, self.store_callback)

    responses = []
    for path in self.paths:
      req = confd_client.ConfdClientRequest(
        type=constants.CONFD_REQ_CONFIG_QUERY, query=path)
      _, response = self.DoConfdRequestReply(req)
      responses.append(str(response.server_reply.answer))
    table = zip(self.paths, responses)
    longest_path = max(len(p) for p in self.paths)
    for p, a in table:
      print "%s\t%s" % (p.ljust(longest_path), a)

  def DoConfdRequestReply(self, req):
    """Send request to Confd and await all responses.

    """
    self.confd_client.SendRequest(req, async=False)
    if not self.confd_client.ReceiveReply():
      Err("Did not receive all expected confd replies")
    return self.store_callback.GetResponse(req.rsalt)


def main():
  """Application entry point.

  """
  QueryClient().Run()


if __name__ == "__main__":
  main()
