#!/usr/bin/python
#

# Copyright (C) 2011 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 translate between ovf and ganeti backup format.

"""

import logging
import optparse
import os

from ganeti import cli
from ganeti import constants
from ganeti import errors
from ganeti import ovf
from ganeti import utils


IMPORT_MODE = "import"
EXPORT_MODE = "export"


def CheckOptions(parser, options_dict, required, forbidden, excluding, mode):
  """Performes check on the command line options.

  Checks whether the required arguments are present and if none of the arguments
  not supported for the current mode are given.

  @type options_dict: list
  @param options_dict: dictionary containing all the options from the command
    line
  @type required: list
  @param required: list of pairs (option, argument) where 'option' is required
    in mode 'mode'
  @type forbidden: list
  @param forbidden: list of pairs (option, argument) which are not allowed in
    mode 'mode'
  @type excluding: list
  @param excluding: list of pairs (argument1, argument2); each pair contains
    mutually exclusive arguments
  @type mode: string
  @param mode: current mode of the converter

  """
  for (option, argument) in required:
    if not options_dict[option]:
      parser.error("Argument %s is required for %s" % (argument, mode))
  for (option, argument) in forbidden:
    if options_dict[option]:
      parser.error("Argument %s is not allowed in %s mode" % (argument, mode))
  for (arg1, arg2) in excluding:
    if options_dict[arg1] and options_dict[arg2]:
      parser.error("Arguments %s and %s exclude each other" % (arg1, arg2))


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

  In case of mismatching parameters, it will show the correct usage and exit.

  @rtype: tuple
  @return: (mode, sourcefile to read from, additional options)

  """
  usage = ("%%prog {%s|%s} <source-cfg-file> [options...]" %
           (IMPORT_MODE, EXPORT_MODE))
  parser = optparse.OptionParser(usage=usage)

  #global options
  parser.add_option(cli.DEBUG_OPT)
  parser.add_option(cli.VERBOSE_OPT)
  parser.add_option("-n", "--name", dest="name", action="store",
                    help="Name of the instance")
  parser.add_option("--output-dir", dest="output_dir",
                    help="Path to the output directory")

  #import options
  import_group = optparse.OptionGroup(parser, "Import options")
  import_group.add_option(cli.BACKEND_OPT)
  import_group.add_option(cli.DISK_OPT)
  import_group.add_option(cli.DISK_TEMPLATE_OPT)
  import_group.add_option(cli.HYPERVISOR_OPT)
  import_group.add_option(cli.NET_OPT)
  import_group.add_option(cli.NONICS_OPT)
  import_group.add_option(cli.OS_OPT)
  import_group.add_option(cli.OSPARAMS_OPT)
  import_group.add_option(cli.TAG_ADD_OPT)
  parser.add_option_group(import_group)

  #export options
  export_group = optparse.OptionGroup(parser, "Export options")
  export_group.add_option("--compress", dest="compression",
                          action="store_true", default=False,
                          help="The exported disk will be compressed to tar.gz")
  export_group.add_option("--external", dest="ext_usage",
                          action="store_true", default=False,
                          help="The package will be used externally (ommits the"
                               " Ganeti-specific parts of configuration)")
  export_group.add_option("-f", "--format", dest="disk_format",
                          action="store",
                          choices=("raw", "cow", "vmdk"),
                          help="Disk format for export (one of raw/cow/vmdk)")
  export_group.add_option("--ova", dest="ova_package",
                          action="store_true", default=False,
                          help="Export everything into OVA package")
  parser.add_option_group(export_group)

  options, args = parser.parse_args()
  if len(args) != 2:
    parser.error("Wrong number of arguments")
  mode = args.pop(0)
  input_path = os.path.abspath(args.pop(0))

  if mode == IMPORT_MODE:
    required = []
    forbidden = [
      ("compression", "--compress"),
      ("disk_format", "--format"),
      ("ext_usage", "--external"),
      ("ova_package", "--ova"),
    ]
    excluding = [("nics", "no_nics")]
  elif mode == EXPORT_MODE:
    required = [("disk_format", "--format")]
    forbidden = [
      ("beparams", "--backend-parameters"),
      ("disk_template", "--disk-template"),
      ("disks", "--disk"),
      ("hypervisor", "--hypervisor-parameters"),
      ("nics", "--net"),
      ("no_nics", "--no-nics"),
      ("os", "--os-type"),
      ("osparams", "--os-parameters"),
      ("tags", "--tags"),
    ]
    excluding = []
  else:
    parser.error("First argument should be either '%s' or '%s'" %
                 (IMPORT_MODE, EXPORT_MODE))

  options_dict = vars(options)
  CheckOptions(parser, options_dict, required, forbidden, excluding, mode)

  return (mode, input_path, options)


def main():
  """Main routine.

  """
  (mode, input_path, options) = ParseOptions()

  utils.SetupToolLogging(options.debug, options.verbose)

  logging.info("Chosen %s mode, reading the %s file", mode, input_path)
  assert mode in (IMPORT_MODE, EXPORT_MODE)
  converter = None
  try:
    if mode == IMPORT_MODE:
      converter = ovf.OVFImporter(input_path, options)
    elif mode == EXPORT_MODE:
      converter = ovf.OVFExporter(input_path, options)
    converter.Parse()
    converter.Save()
  except errors.OpPrereqError, err:
    if converter:
      converter.Cleanup()
    logging.exception(err)
    return constants.EXIT_FAILURE


if __name__ == "__main__":
  main()
