#!/usr/bin/python
#

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


"""Helpers for testing import-export daemon"""

import os
import sys
import errno
import time

from ganeti import constants
from ganeti import utils
from ganeti import objects
from ganeti import serializer


RETRY_INTERVAL = (0.1, 1.1, 1)
TIMEOUT = int(os.getenv("TIMEOUT", 30))
VALIDITY = int(os.getenv("VALIDITY", 1))


def Log(msg, *args):
  if args:
    line = msg % args
  else:
    line = msg

  sys.stderr.write("%0.6f, pid %s: %s\n" % (time.time(), os.getpid(), line))
  sys.stderr.flush()


def _GetImportExportData(filename):
  try:
    data = utils.ReadFile(filename)
  except EnvironmentError, err:
    Log("%s = %s", filename, err)
    if err.errno != errno.ENOENT:
      raise
    raise utils.RetryAgain()

  Log("%s = %s", filename, data.strip())

  return objects.ImportExportStatus.FromDict(serializer.LoadJson(data))


def _CheckConnected(filename):
  if not _GetImportExportData(filename).connected:
    Log("Not connected")
    raise utils.RetryAgain()

  Log("Connected")


def _CheckListenPort(filename):
  port = _GetImportExportData(filename).listen_port
  if not port:
    Log("No port")
    raise utils.RetryAgain()
  Log("Listening on %s", port)
  return port


def WaitForListenPort(filename):
  return utils.Retry(_CheckListenPort, RETRY_INTERVAL, TIMEOUT,
                     args=(filename, ))


def WaitForConnected(filename):
  utils.Retry(_CheckConnected, RETRY_INTERVAL, TIMEOUT, args=(filename, ))


def main():
  (filename, what) = sys.argv[1:]

  Log("Running helper for %s %s", filename, what)

  if what == "listen-port":
    print WaitForListenPort(filename)
  elif what == "connected":
    WaitForConnected(filename)
  elif what == "gencert":
    utils.GenerateSelfSignedSslCert(filename, 1, validity=VALIDITY)
  else:
    raise Exception("Unknown command '%s'" % what)


if __name__ == "__main__":
  main()
