# Copyright 2017 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import logging

import common
from autotest_lib.client.bin import utils
from autotest_lib.client.common_lib import error
from autotest_lib.site_utils.lxc import constants
from autotest_lib.site_utils.lxc import container

try:
    from autotest_lib.utils.frozen_chromite.lib import metrics
except ImportError:
    metrics = utils.metrics_mock


class ContainerFactory(object):
    """A factory class for creating LXC container objects."""

    def __init__(self, base_container, container_class=container.Container,
                 snapshot=True, force_cleanup=False,
                 lxc_path=constants.DEFAULT_CONTAINER_PATH):
        """Initializes a ContainerFactory.

        @param base_container: The base container from which other containers
                               are cloned.
        @param container_class: (optional) The Container class to instantiate.
                                By default, lxc.Container is instantiated.
        @param snapshot: (optional) If True, creates LXC snapshot clones instead
                         of full clones.  By default, snapshot clones are used.
        @param force_cleanup: (optional) If True, if a container is created with
                              a name and LXC directory matching an existing
                              container, the existing container is destroyed,
                              and the new container created in its place. By
                              default, existing containers are not destroyed and
                              a ContainerError is raised.
        @param lxc_path: (optional) The default LXC path that will be used for
                         new containers.  If one is not provided, the
                         DEFAULT_CONTAINER_PATH from lxc.constants will be used.
                         Note that even if a path is provided here, it can still
                         be overridden when create_container is called.
        """
        self._container_class = container_class
        self._base_container = base_container
        self._snapshot = snapshot
        self._force_cleanup = force_cleanup
        self._lxc_path = lxc_path


    def create_container(self, cid=None, lxc_path=None):
        """Creates a new container.

        @param cid: (optional) A ContainerId for the new container.  If an ID is
                    provided, it determines both the name and the ID of the
                    container.  If no ID is provided, a random name is generated
                    for the container, and it is not assigned an ID.
        @param lxc_path: (optional) The LXC path for the new container.  If one
                         is not provided, the factory's default lxc_path
                         (specified when the factory was constructed) is used.
        """
        name = str(cid) if cid else None
        if lxc_path is None:
            lxc_path = self._lxc_path

        logging.debug('Creating new container (name: %s, lxc_path: %s)',
                      name, lxc_path)

        # If an ID is provided, use it as the container name.
        new_container = self._create_from_base(name, lxc_path)
        # If an ID is provided, assign it to the container.  When the container
        # is created just-in-time by the container bucket, this ensures that the
        # resulting container is correctly registered with the autoserv system.
        # If the container is being created by a container pool, the ID will be
        # assigned later, when the continer is bound to an actual test process.
        if cid:
            new_container.id = cid
        return new_container


    # create_from_base_duration is the original name of the metric.  Keep this
    # so we have history.
    @metrics.SecondsTimerDecorator(
            '%s/create_from_base_duration' % constants.STATS_KEY)
    def _create_from_base(self, name, lxc_path):
        """Creates a container from the base container.

        @param name: Name of the container.
        @param lxc_path: The LXC path of the new container.

        @return: A Container object for the created container.

        @raise ContainerError: If the container already exist.
        @raise error.CmdError: If lxc-clone call failed for any reason.
        """
        use_snapshot = constants.SUPPORT_SNAPSHOT_CLONE and self._snapshot

        try:
            return self._container_class.clone(src=self._base_container,
                                               new_name=name,
                                               new_path=lxc_path,
                                               snapshot=use_snapshot,
                                               cleanup=self._force_cleanup)
        except error.CmdError:
            if not use_snapshot:
                raise
            else:
                logging.debug(
                        'Creating snapshot clone failed.'
                        ' Attempting without snapshot...'
                        ' This forces cleanup of old cloned container.'
                )
                return self._container_class.clone(src=self._base_container,
                                                   new_name=name,
                                                   new_path=lxc_path,
                                                   snapshot=False,
                                                   cleanup=True)
