# Copyright 2020 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 json
import logging
import os
import shutil

from autotest_lib.client.common_lib import utils

_DEFAULT_RUN = utils.run

# Directory for preloaded DLCs that may be packaged with the OS. Preloaded
# DLCs can be installed without needing to go through update_engine.
_PRELOAD_DIR = '/mnt/stateful_partition/var_overlay/cache/dlc-images/'

class DLCUtil(object):
    """
    Wrapper around dlcservice_util for tests that require DLC management.

    For dlc_util to work seamlessly in both client and server tests, we need
    those tests to define the _run() function:
    server side: host.run
    client side: utils.run

    """
    _DLCSERVICE_UTIL_CMD = "dlcservice_util"
    _SAMPLE_DLC_ID = "sample-dlc"

    def __init__(self, run_func=_DEFAULT_RUN):
        """
        Initialize this class with _run() function.

        @param run_func: The function to use to run commands on the client.
                         Defaults for use by client tests, but can be
                         overwritten to run remotely from a server test.

        """
        self._run = run_func


    def list(self):
        """
        List DLCs that are installed on the DUT and additional information
        about them such as name, version, root_mount, and size. The output is
        a dictionary containing the result of dlcservice_util --list, which
        looks like:
        {
           "sample-dlc": [ {
              "fs-type": "squashfs",
              "id": "sample-dlc",
              "image_type": "dlc",
              "manifest": "/opt/google/dlc/sample-dlc/package/imageloader.json",
              "name": "Sample DLC",
              "package": "package",
              "preallocated_size": "4194304",
              "root_mount": "/run/imageloader/sample-dlc/package",
              "size": "53248",
              "version": "1.0.0-r10"
           } ]
        }

        @return Dictionary containing information about the installed DLCs,
                whose keys are the DLC IDs.

        """
        status = self._run([self._DLCSERVICE_UTIL_CMD, '--list'])
        logging.info(status)

        return json.loads(status.stdout)


    def install(self, dlc_id, omaha_url, timeout=900):
        """
        Install a DLC on the stateful partition.

        @param dlc_id: The id of the DLC to install.
        @param omaha_url: The Omaha URL to send the install request to.

        """
        cmd = [self._DLCSERVICE_UTIL_CMD, '--install', '--id=%s' % dlc_id,
               '--omaha_url=%s' % omaha_url]
        self._run(cmd, timeout=timeout)


    def uninstall(self, dlc_id, ignore_status=False):
        """
        Uninstall a DLC. The DLC will remain on the DUT in an un-mounted state
        and can be reinstalled without requiring an install request. To
        completely remove a DLC, purge it instead.

        @param dlc_id: The id of the DLC to uninstall.
        @param ignore_status: Whether or not to ignore the return status when
                              running the uninstall command.

        """
        cmd = [self._DLCSERVICE_UTIL_CMD, '--uninstall', '--id=%s' % dlc_id]
        self._run(cmd, ignore_status=ignore_status)


    def purge(self, dlc_id, ignore_status=False):
        """
        Purge a DLC. This will completely remove the DLC from the device.

        @param dlc_id: The id of the DLC to purge.
        @param ignore_status: Whether or not to ignore the return status when
                              running the purge command.

        """
        cmd = [self._DLCSERVICE_UTIL_CMD, '--purge', '--id=%s' % dlc_id]
        self._run(cmd, ignore_status=ignore_status)


    def remove_preloaded(self, dlc_id):
        """
        Remove a DLC from the preload directory. DLCs in this directory can be
        preloaded, meaning they can be installed without needing to download
        and install them using update_engine. It is hard to differentiate
        preloading a DLC and installing a DLC after a successful AU. After
        AU, updated DLCs should be installed but not yet mounted. In both
        cases, calling dlcservice_util --install should result in the DLC
        being installed without going through Omaha/Nebraska. Clearing the
        preload directory for a DLC allows us to verify it was updated,
        by ruling out the possibility that it was preloaded instead.

        @param dlc_id: Wipe preload directory for the DLC with this id.

        """
        preload_dir = os.path.join(_PRELOAD_DIR, dlc_id)
        if os.path.exists(preload_dir) and os.path.isdir(preload_dir):
            shutil.rmtree(preload_dir)


    def is_installed(self, dlc_id):
        """
        Check if a DLC is installed.

        @param dlc_id: The id of the DLC to check.

        @return True if the DLC is installed, False if it's not.

        """
        return dlc_id in self.list().keys()
