#
#

# Copyright (C) 2006, 2007, 2008, 2013 Google Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.


"""Fake hypervisor

"""

import os
import os.path
import logging

from ganeti import utils
from ganeti import constants
from ganeti import errors
from ganeti import objects
from ganeti import pathutils
from ganeti.hypervisor import hv_base


class FakeHypervisor(hv_base.BaseHypervisor):
  """Fake hypervisor interface.

  This can be used for testing the ganeti code without having to have
  a real virtualisation software installed.

  """
  PARAMETERS = {
    constants.HV_MIGRATION_MODE: hv_base.MIGRATION_MODE_CHECK,
    }

  CAN_MIGRATE = True

  _ROOT_DIR = pathutils.RUN_DIR + "/fake-hypervisor"

  def __init__(self):
    hv_base.BaseHypervisor.__init__(self)
    utils.EnsureDirs([(self._ROOT_DIR, constants.RUN_DIRS_MODE)])

  def ListInstances(self, hvparams=None):
    """Get the list of running instances.

    """
    return os.listdir(self._ROOT_DIR)

  def GetInstanceInfo(self, instance_name, hvparams=None):
    """Get instance properties.

    @type instance_name: string
    @param instance_name: the instance name
    @type hvparams: dict of strings
    @param hvparams: hvparams to be used with this instance

    @return: tuple of (name, id, memory, vcpus, stat, times)

    """
    file_name = self._InstanceFile(instance_name)
    if not os.path.exists(file_name):
      return None
    try:
      fh = open(file_name, "r")
      try:
        inst_id = fh.readline().strip()
        memory = utils.TryConvert(int, fh.readline().strip())
        vcpus = utils.TryConvert(int, fh.readline().strip())
        stat = "---b-"
        times = "0"
        return (instance_name, inst_id, memory, vcpus, stat, times)
      finally:
        fh.close()
    except IOError, err:
      raise errors.HypervisorError("Failed to list instance %s: %s" %
                                   (instance_name, err))

  def GetAllInstancesInfo(self, hvparams=None):
    """Get properties of all instances.

    @type hvparams: dict of strings
    @param hvparams: hypervisor parameter
    @return: list of tuples (name, id, memory, vcpus, stat, times)

    """
    data = []
    for file_name in os.listdir(self._ROOT_DIR):
      try:
        fh = open(utils.PathJoin(self._ROOT_DIR, file_name), "r")
        inst_id = "-1"
        memory = 0
        vcpus = 1
        stat = "-----"
        times = "-1"
        try:
          inst_id = fh.readline().strip()
          memory = utils.TryConvert(int, fh.readline().strip())
          vcpus = utils.TryConvert(int, fh.readline().strip())
          stat = "---b-"
          times = "0"
        finally:
          fh.close()
        data.append((file_name, inst_id, memory, vcpus, stat, times))
      except IOError, err:
        raise errors.HypervisorError("Failed to list instances: %s" % err)
    return data

  @classmethod
  def _InstanceFile(cls, instance_name):
    """Compute the instance file for an instance name.

    """
    return utils.PathJoin(cls._ROOT_DIR, instance_name)

  def _IsAlive(self, instance_name):
    """Checks if an instance is alive.

    """
    file_name = self._InstanceFile(instance_name)
    return os.path.exists(file_name)

  def _MarkUp(self, instance, memory):
    """Mark the instance as running.

    This does no checks, which should be done by its callers.

    """
    file_name = self._InstanceFile(instance.name)
    fh = file(file_name, "w")
    try:
      fh.write("0\n%d\n%d\n" %
               (memory,
                instance.beparams[constants.BE_VCPUS]))
    finally:
      fh.close()

  def _MarkDown(self, instance_name):
    """Mark the instance as running.

    This does no checks, which should be done by its callers.

    """
    file_name = self._InstanceFile(instance_name)
    utils.RemoveFile(file_name)

  def StartInstance(self, instance, block_devices, startup_paused):
    """Start an instance.

    For the fake hypervisor, it just creates a file in the base dir,
    creating an exception if it already exists. We don't actually
    handle race conditions properly, since these are *FAKE* instances.

    """
    if self._IsAlive(instance.name):
      raise errors.HypervisorError("Failed to start instance %s: %s" %
                                   (instance.name, "already running"))
    try:
      self._MarkUp(instance, self._InstanceStartupMemory(instance))
    except IOError, err:
      raise errors.HypervisorError("Failed to start instance %s: %s" %
                                   (instance.name, err))

  def StopInstance(self, instance, force=False, retry=False, name=None,
                   timeout=None):
    """Stop an instance.

    For the fake hypervisor, this just removes the file in the base
    dir, if it exist, otherwise we raise an exception.

    """
    assert(timeout is None or force is not None)

    if name is None:
      name = instance.name
    if not self._IsAlive(name):
      raise errors.HypervisorError("Failed to stop instance %s: %s" %
                                   (name, "not running"))
    self._MarkDown(name)

  def RebootInstance(self, instance):
    """Reboot an instance.

    For the fake hypervisor, this does nothing.

    """
    return

  def BalloonInstanceMemory(self, instance, mem):
    """Balloon an instance memory to a certain value.

    @type instance: L{objects.Instance}
    @param instance: instance to be accepted
    @type mem: int
    @param mem: actual memory size to use for instance runtime

    """
    if not self._IsAlive(instance.name):
      raise errors.HypervisorError("Failed to balloon memory for %s: %s" %
                                   (instance.name, "not running"))
    try:
      self._MarkUp(instance, mem)
    except EnvironmentError, err:
      raise errors.HypervisorError("Failed to balloon memory for %s: %s" %
                                   (instance.name, utils.ErrnoOrStr(err)))

  def GetNodeInfo(self, hvparams=None):
    """Return information about the node.

    See L{BaseHypervisor.GetLinuxNodeInfo}.

    """
    result = self.GetLinuxNodeInfo()
    # substract running instances
    all_instances = self.GetAllInstancesInfo()
    result["memory_free"] -= min(result["memory_free"],
                                 sum([row[2] for row in all_instances]))
    return result

  @classmethod
  def GetInstanceConsole(cls, instance, primary_node, hvparams, beparams):
    """Return information for connecting to the console of an instance.

    """
    return objects.InstanceConsole(instance=instance.name,
                                   kind=constants.CONS_MESSAGE,
                                   message=("Console not available for fake"
                                            " hypervisor"))

  def Verify(self, hvparams=None):
    """Verify the hypervisor.

    For the fake hypervisor, it just checks the existence of the base
    dir.

    @type hvparams: dict of strings
    @param hvparams: hypervisor parameters to be verified against; not used
      for fake hypervisors

    @return: Problem description if something is wrong, C{None} otherwise

    """
    if os.path.exists(self._ROOT_DIR):
      return None
    else:
      return "The required directory '%s' does not exist" % self._ROOT_DIR

  @classmethod
  def PowercycleNode(cls, hvparams=None):
    """Fake hypervisor powercycle, just a wrapper over Linux powercycle.

    @type hvparams: dict of strings
    @param hvparams: hypervisor params to be used on this node

    """
    cls.LinuxPowercycle()

  def AcceptInstance(self, instance, info, target):
    """Prepare to accept an instance.

    @type instance: L{objects.Instance}
    @param instance: instance to be accepted
    @type info: string
    @param info: instance info, not used
    @type target: string
    @param target: target host (usually ip), on this node

    """
    if self._IsAlive(instance.name):
      raise errors.HypervisorError("Can't accept instance, already running")

  def MigrateInstance(self, cluster_name, instance, target, live):
    """Migrate an instance.

    @type cluster_name: string
    @param cluster_name: name of the cluster
    @type instance: L{objects.Instance}
    @param instance: the instance to be migrated
    @type target: string
    @param target: hostname (usually ip) of the target node
    @type live: boolean
    @param live: whether to do a live or non-live migration

    """
    logging.debug("Fake hypervisor migrating %s to %s (live=%s)",
                  instance, target, live)

  def FinalizeMigrationDst(self, instance, info, success):
    """Finalize the instance migration on the target node.

    For the fake hv, this just marks the instance up.

    @type instance: L{objects.Instance}
    @param instance: instance whose migration is being finalized
    @type info: string/data (opaque)
    @param info: migration information, from the source node
    @type success: boolean
    @param success: whether the migration was a success or a failure

    """
    if success:
      self._MarkUp(instance, self._InstanceStartupMemory(instance))
    else:
      # ensure it's down
      self._MarkDown(instance.name)

  def PostMigrationCleanup(self, instance):
    """Clean-up after a migration.

    To be executed on the source node.

    @type instance: L{objects.Instance}
    @param instance: the instance that was migrated

    """
    pass

  def FinalizeMigrationSource(self, instance, success, live):
    """Finalize the instance migration on the source node.

    @type instance: L{objects.Instance}
    @param instance: the instance that was migrated
    @type success: bool
    @param success: whether the migration succeeded or not
    @type live: bool
    @param live: whether the user requested a live migration or not

    """
    # pylint: disable=W0613
    if success:
      self._MarkDown(instance.name)

  def GetMigrationStatus(self, instance):
    """Get the migration status

    The fake hypervisor migration always succeeds.

    @type instance: L{objects.Instance}
    @param instance: the instance that is being migrated
    @rtype: L{objects.MigrationStatus}
    @return: the status of the current migration (one of
             L{constants.HV_MIGRATION_VALID_STATUSES}), plus any additional
             progress info that can be retrieved from the hypervisor

    """
    return objects.MigrationStatus(status=constants.HV_MIGRATION_COMPLETED)
