# Lint as: python2, python3
# Copyright 2022 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# Expects to be run in an environment with sudo and no interactive password
# prompt, such as within the Chromium OS development chroot.
"""Host class for GSC devboard connected host."""

import contextlib
import logging
import os
import time

try:
    import docker
except ImportError:
    logging.info("Docker API is not installed in this environment")

from autotest_lib.server.hosts import host_info
from autotest_lib.server.hosts import remote

# Create this file in the chroot home directory
# containing the image to use in place of the default.
SERVICE_IMAGE_OVERRIDE = "gsc_dev_board_override"

# Create this file in the chroot home directory
# containing the image token file to enable image pull.
# gcloud auth print-access-token > /chroot/home/${USER}/gsc_dev_board_token
SERVICE_IMAGE_TOKEN_FILE = "gsc_dev_board_token"

SERVICE_IMAGE_DEFAULT = "gcr.io/satlab-images/gsc_dev_board:release"

SERVICE_START_TIMEOUT = 5

SATLAB_DOCKER_HOST = 'tcp://192.168.231.1:2375'
LOCAL_DOCKER_HOST = 'tcp://127.0.0.1:2375'
DEFAULT_DOCKER_HOST = 'unix:///var/run/docker.sock'

DEFAULT_SERVICE_PORT = 39999

ULTRADEBUG = '18d1:0304'
TI50 = '18d1:504a'

# Host Info Attributes
ULTRADEBUG_SERIAL_ATTR = 'ultradebug_serial'
DEVBOARD_TYPE_ATTR = 'devboard_type'
ANDREIBOARD_TYPE = 'andreiboard'

def IsGSCDevboardHost(hostname):
    """ Returns True iff the hostname is a GSC devboard. """
    return ANDREIBOARD_TYPE in hostname

class GSCDevboardHost(remote.RemoteHost):
    """
    A host that is physically connected to a GSC devboard.

    It could either be a SDK workstation (chroot) or a SatLab box.
    """

    def _initialize(self,
                    hostname,
                    service_debugger_serial=None,
                    service_ip="",
                    service_port=DEFAULT_SERVICE_PORT,
                    service_gsc_serial=None,
                    host_info_store=None,
                    *args,
                    **dargs):
        """Construct a GSCDevboardHost object.

        @hostname: Name of the devboard host, will be used in future to look up
                   the debugger serial, not currently used.
        @service_debugger_serial: debugger connected to devboard, defaults to
                                  the first one found on the container.
        @service_ip: devboard service ip, default is to start a new container.
        @service_port: devboard service port, defaults to 39999.
        """

        super(GSCDevboardHost, self)._initialize(hostname, *args, **dargs)

        self._dut_name = hostname
        #Tast will not make any connections to '-'
        self.hostname = '-'
        self.port = None

        self.host_info_store = (host_info_store or
                                host_info.InMemoryHostInfoStore())

        hi = self.host_info_store.get()

        # Populate unset params from host info store.
        hi_devboard_type = hi.attributes.get(DEVBOARD_TYPE_ATTR)
        if hi_devboard_type == ANDREIBOARD_TYPE:
            hi_ultradebug_serial = hi.attributes.get(ULTRADEBUG_SERIAL_ATTR)
            if service_debugger_serial is None and hi_ultradebug_serial is not None:
                logging.info('Using andreiboard ultradebug %s from host_info_store', hi_ultradebug_serial)
                service_debugger_serial = hi_ultradebug_serial

        # Use docker host from environment or by probing a list of candidates.
        self._client = None

        self._docker_container = None
        self._service_ip = service_ip
        self._service_port = service_port
        self._prestart = None
        logging.info("Using service port %s", self._service_port)

        if len(service_ip) > 0 and not service_ip.startswith('detect_'):
            return

        try:
            logging.info('Trying docker host from env')
            self._client = docker.from_env()
            logging.info("Created docker host from env")
        except NameError:
            raise NameError('Please install docker using '
                            '"autotest/files/utils/install_docker_chroot.sh"')
        except docker.errors.DockerException:
            docker_host = None
            candidate_hosts = [
                    SATLAB_DOCKER_HOST, DEFAULT_DOCKER_HOST, LOCAL_DOCKER_HOST
            ]
            for h in candidate_hosts:
                try:
                    logging.info('Trying docker host at {}'.format(h))
                    c = docker.DockerClient(base_url=h, timeout=2)
                    c.close()
                    docker_host = h
                    break
                except docker.errors.DockerException:
                    pass
            if docker_host is not None:
                self._client = docker.DockerClient(base_url=docker_host,
                                                   timeout=300)
            else:
                raise ValueError('Invalid DOCKER_HOST, ensure dockerd is'
                                 ' running.')
            logging.info("Using docker host at %s", docker_host)

        self._satlab = False
        # GSCDevboardHost should only be created on Satlab or localhost, so
        # assume Satlab if a drone container is running.
        if len(self._client.containers.list(filters={'name': 'drone'})) > 0:
            logging.info("In Satlab")
            self._satlab = True

        image_override = os.path.join(os.path.expanduser('~'),
                                      SERVICE_IMAGE_OVERRIDE)
        logging.info('Checking docker image override at %s', image_override)
        if os.path.exists(image_override):
            logging.info('Using docker image override')
            with open(image_override) as f:
                self._docker_image = f.readline().strip()
        else:
            self._docker_image = SERVICE_IMAGE_DEFAULT

        #TODO(b/257333832): Migrate to CFT to manage image on Satlab.
        token_file = os.path.join(os.path.expanduser('~'),
                                  SERVICE_IMAGE_TOKEN_FILE)
        if not self._satlab and os.path.isfile(token_file):
            try:
                with open(token_file) as f:
                    token = f.readline().strip()

                    logging.info('Pulling image %s', self._docker_image)
                    self._client.login('oauth2accesstoken', token,
                                       registry='https://gcr.io')
                    self._client.images.pull(self._docker_image)
            except docker.errors.NotFound:
                logging.info('Image not found in registry: %s, assuming local.',
                             self._docker_image)
                pass
            except docker.errors.APIError as e:
                logging.info('Failed to pull %s: %s, local image may be '
                             'outdated.', self._docker_image, e)

        self._docker_network = 'default_satlab' if self._satlab else 'host'

        def prestart():
            self._service_debugger_serial = self._get_valid_serial(ULTRADEBUG,
                service_debugger_serial)
            self._service_gsc_serial = self._get_valid_serial(TI50,
                service_gsc_serial)

            if (self._service_debugger_serial == "" and
                self._service_gsc_serial == ""):
                raise ValueError('No valid debugger nor gsc found')

            logging.info("Using debugger %s", self._service_debugger_serial)
            logging.info("Using gsc %s", self._service_gsc_serial)

            self._docker_container_name = "gsc_dev_board_{}".format(
                    self._service_debugger_serial)

        self._prestart = prestart


    def _get_valid_serial(self, vidpid, serial):
        """
        Gets a valid serial of vidpid that satisfies the provided serial.

        serial is empty string -> device unused(empty string is returned).
        serial is None -> find unique device(else empty string is returned).
        serial is given -> must find device(else an error is raised).
        """
        if serial == "":
            return ""

        logging.info("Attempt to find serial given %s", serial)

        serials = self._list_usb_serials(vidpid)

        logging.info("Available %s serials: [%s]", vidpid, ', '.join(serials))

        if serial is None:
            return serials[0] if len(serials) == 1 else ""
        if serial in serials:
            return serial
        else:
            raise ValueError('No debuggers found matching %s' % serial)


    def _list_usb_serials(self, vidpid):
        """List all attached devices of vidpid."""

        cmd = ['lsusb', '-v', '-d', vidpid]
        try:
            output = self._client.containers.run(self._docker_image,
                                        cmd,
                                        remove=True,
                                        privileged=True,
                                        volumes=["/dev:/dev"])

            output = output.decode("utf-8").split('\n')
        except docker.errors.ContainerError:
            return []

        serials = [
                l.strip().split(' ')[-1] for l in output
                if l.strip()[:7] == 'iSerial'
        ]

        if not serials:
            logging.info('Could not find any serials for %s in: %s', vidpid,
                         output)

        return serials


    @contextlib.contextmanager
    def service_context(self):
        """Service context manager that provides the service endpoint."""
        self.start_service()
        try:
            yield "{}:{}".format(self.service_ip, self.service_port)
        finally:
            self.stop_service()

    def start_service(self):
        """Starts service if needed."""

        if self._docker_container is not None:
            return

        # Adopt the convention that devboard containers are named
        # gsc_dev_board_[dt_ab|ot_fpga_cw310|he]
        if self._service_ip.startswith("detect_"):
            container_name = "gsc_dev_board_" + self._service_ip[7:]
            c = self._client.containers.get(container_name)
            settings = c.attrs['NetworkSettings']
            self._service_ip = settings['Networks'][
                    self._docker_network]['IPAddress']
            logging.info('Detected service ip %s', self._service_ip)

        if self._service_ip:
            # Assume container already exists if service_ip was set
            logging.info("Skip start_service due to set service_ip")
            return

        if self._prestart is not None:
            self._prestart()

        environment = {
                'DEVBOARDSVC_PORT': self._service_port,
                'DEBUGGER_SERIAL': self._service_debugger_serial,
                'GSC_SERIAL': self._service_gsc_serial
        }
        start_cmd = ['/opt/gscdevboard/start_devboardsvc.sh']

        # Stop any leftover containers
        try:
            c = self._client.containers.get(self._docker_container_name)
            c.remove(force=True)
        except docker.errors.APIError:
            pass

        self._docker_container = self._client.containers.run(self._docker_image,
                                    remove=True,
                                    privileged=True,
                                    name=self._docker_container_name,
                                    hostname=self._docker_container_name,
                                    network=self._docker_network,
                                    cap_add=["NET_ADMIN"],
                                    detach=True,
                                    volumes=["/dev:/dev"],
                                    environment=environment,
                                    command=start_cmd)

        deadline = time.time() + SERVICE_START_TIMEOUT
        while time.time() <= deadline:
            try:
                log = ''
                self._docker_container.reload()
                _, log = self._docker_container.exec_run(
                        ['bash', '-c', 'cat /var/log/devboardsvc_*.log'],
                        stream=True
                    )
                log = '\n'.join(l.decode("utf-8") for l in log)
                if 'Server started' in log:
                    logging.info('Using service ip %s', self.service_ip)
                    return
                if 'Server failed to start' in log:
                    break
            except docker.errors.APIError:
                break

        logging.debug('Last logs from service: %s', log)
        self.stop_service()
        raise RuntimeError('Server failed to start, check if port is already used.')


    def stop_service(self):
        """Stops service by killing the container."""
        if self._docker_container is None:
            return

        try:
            self._docker_container.kill()
        except docker.errors.NotFound:
            logging.debug('Service container already stopped.')

        self._docker_container = None


    @property
    def service_port(self):
        """Return service port (local to the container host)."""
        return self._service_port

    @property
    def service_ip(self):
        """Return service ip (local to the container host)."""
        if self._service_ip is not None:
            return self._service_ip

        if self._docker_network == 'host':
            return '127.0.0.1'
        else:
            if self._docker_container is None:
                return ''
            else:
                settings = self._docker_container.attrs['NetworkSettings']
                return settings['Networks'][self._docker_network]['IPAddress']

    def job_start(self):
        """ Start job, no-op """
        pass

    def run(self, command, **argv):
        """ Run command, ignored """
        logging.warn('GSCDevboardHost does not support run: %s', command)

    def run_background(self, command, **argv):
        """ Run command in background, ignored """
        logging.warn('GSCDevboardHost does not support run_background: %s', command)
