# Copyright 2018 - The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
r"""Instance class.

Define the instance class used to hold details about an AVD instance.

The instance class will hold details about AVD instances (remote/local) used to
enable users to understand what instances they've created. This will be leveraged
for the list, delete, and reconnect commands.

The details include:
- instance name (for remote instances)
- creation date/instance duration
- instance image details (branch/target/build id)
- and more!
"""

import collections
import datetime
import logging
import os
import re
import subprocess
import tempfile

# pylint: disable=import-error
import dateutil.parser
import dateutil.tz

from acloud.internal import constants
from acloud.internal.lib import cvd_runtime_config
from acloud.internal.lib import utils
from acloud.internal.lib.adb_tools import AdbTools
from acloud.internal.lib.local_instance_lock import LocalInstanceLock


logger = logging.getLogger(__name__)

_ACLOUD_CVD_TEMP = os.path.join(tempfile.gettempdir(), "acloud_cvd_temp")
_CVD_RUNTIME_FOLDER_NAME = "cuttlefish_runtime"
_CVD_STATUS_BIN = "cvd_status"
_MSG_UNABLE_TO_CALCULATE = "Unable to calculate"
_NO_ANDROID_ENV = "android source not available"
_RE_GROUP_ADB = "local_adb_port"
_RE_GROUP_VNC = "local_vnc_port"
_RE_SSH_TUNNEL_PATTERN = (r"((.*\s*-L\s)(?P<%s>\d+):127.0.0.1:%s)"
                          r"((.*\s*-L\s)(?P<%s>\d+):127.0.0.1:%s)"
                          r"(.+%s)")
_RE_TIMEZONE = re.compile(r"^(?P<time>[0-9\-\.:T]*)(?P<timezone>[+-]\d+:\d+)$")

_COMMAND_PS_LAUNCH_CVD = ["ps", "-wweo", "lstart,cmd"]
_RE_RUN_CVD = re.compile(r"(?P<date_str>^[^/]+)(.*run_cvd)")
_DISPLAY_STRING = "%(x_res)sx%(y_res)s (%(dpi)s)"
_RE_ZONE = re.compile(r".+/zones/(?P<zone>.+)$")
_LOCAL_ZONE = "local"
_FULL_NAME_STRING = ("device serial: %(device_serial)s (%(instance_name)s) "
                     "elapsed time: %(elapsed_time)s")
_INDENT = " " * 3
LocalPorts = collections.namedtuple("LocalPorts", [constants.VNC_PORT,
                                                   constants.ADB_PORT])


def GetDefaultCuttlefishConfig():
    """Get the path of default cuttlefish instance config.

    Return:
        String, path of cf runtime config.
    """
    return os.path.join(os.path.expanduser("~"), _CVD_RUNTIME_FOLDER_NAME,
                        constants.CUTTLEFISH_CONFIG_FILE)


def GetLocalInstanceName(local_instance_id):
    """Get local cuttlefish instance name by instance id.

    Args:
        local_instance_id: Integer of instance id.

    Return:
        String, the instance name.
    """
    return "%s-%d" % (constants.LOCAL_INS_NAME, local_instance_id)


def GetLocalInstanceConfig(local_instance_id):
    """Get the path of instance config.

    Args:
        local_instance_id: Integer of instance id.

    Return:
        String, path of cf runtime config.
    """
    cfg_path = os.path.join(GetLocalInstanceRuntimeDir(local_instance_id),
                            constants.CUTTLEFISH_CONFIG_FILE)
    if os.path.isfile(cfg_path):
        return cfg_path
    return None


def GetAllLocalInstanceConfigs():
    """Get the list of instance config.

    Return:
        List of instance config path.
    """
    cfg_list = []
    # Check if any instance config is under home folder.
    cfg_path = GetDefaultCuttlefishConfig()
    if os.path.isfile(cfg_path):
        cfg_list.append(cfg_path)

    # Check if any instance config is under acloud cvd temp folder.
    if os.path.exists(_ACLOUD_CVD_TEMP):
        for ins_name in os.listdir(_ACLOUD_CVD_TEMP):
            cfg_path = os.path.join(_ACLOUD_CVD_TEMP,
                                    ins_name,
                                    _CVD_RUNTIME_FOLDER_NAME,
                                    constants.CUTTLEFISH_CONFIG_FILE)
            if os.path.isfile(cfg_path):
                cfg_list.append(cfg_path)
    return cfg_list


def GetLocalInstanceHomeDir(local_instance_id):
    """Get local instance home dir according to instance id.

    Args:
        local_instance_id: Integer of instance id.

    Return:
        String, path of instance home dir.
    """
    return os.path.join(_ACLOUD_CVD_TEMP,
                        GetLocalInstanceName(local_instance_id))


def GetLocalInstanceLock(local_instance_id):
    """Get local instance lock.

    Args:
        local_instance_id: Integer of instance id.

    Returns:
        LocalInstanceLock object.
    """
    file_path = os.path.join(_ACLOUD_CVD_TEMP,
                             GetLocalInstanceName(local_instance_id) + ".lock")
    return LocalInstanceLock(file_path)


def GetLocalInstanceRuntimeDir(local_instance_id):
    """Get instance runtime dir

    Args:
        local_instance_id: Integer of instance id.

    Return:
        String, path of instance runtime dir.
    """
    return os.path.join(GetLocalInstanceHomeDir(local_instance_id),
                        _CVD_RUNTIME_FOLDER_NAME)


def _GetCurrentLocalTime():
    """Return a datetime object for current time in local time zone."""
    return datetime.datetime.now(dateutil.tz.tzlocal())


def _GetElapsedTime(start_time):
    """Calculate the elapsed time from start_time till now.

    Args:
        start_time: String of instance created time.

    Returns:
        datetime.timedelta of elapsed time, _MSG_UNABLE_TO_CALCULATE for
        datetime can't parse cases.
    """
    match = _RE_TIMEZONE.match(start_time)
    try:
        # Check start_time has timezone or not. If timezone can't be found,
        # use local timezone to get elapsed time.
        if match:
            return _GetCurrentLocalTime() - dateutil.parser.parse(start_time)

        return _GetCurrentLocalTime() - dateutil.parser.parse(
            start_time).replace(tzinfo=dateutil.tz.tzlocal())
    except ValueError:
        logger.debug(("Can't parse datetime string(%s)."), start_time)
        return _MSG_UNABLE_TO_CALCULATE


# pylint: disable=useless-object-inheritance
class Instance(object):
    """Class to store data of instance."""

    # pylint: disable=too-many-locals
    def __init__(self, name, fullname, display, ip, status=None, adb_port=None,
                 vnc_port=None, ssh_tunnel_is_connected=None, createtime=None,
                 elapsed_time=None, avd_type=None, avd_flavor=None,
                 is_local=False, device_information=None, zone=None):
        self._name = name
        self._fullname = fullname
        self._status = status
        self._display = display  # Resolution and dpi
        self._ip = ip
        self._adb_port = adb_port  # adb port which is forwarding to remote
        self._vnc_port = vnc_port  # vnc port which is forwarding to remote
        # True if ssh tunnel is still connected
        self._ssh_tunnel_is_connected = ssh_tunnel_is_connected
        self._createtime = createtime
        self._elapsed_time = elapsed_time
        self._avd_type = avd_type
        self._avd_flavor = avd_flavor
        self._is_local = is_local  # True if this is a local instance
        self._device_information = device_information
        self._zone = zone

    def __repr__(self):
        """Return full name property for print."""
        return self._fullname

    def Summary(self):
        """Let's make it easy to see what this class is holding."""
        representation = []
        representation.append(" name: %s" % self._name)
        representation.append("%s IP: %s" % (_INDENT, self._ip))
        representation.append("%s create time: %s" % (_INDENT, self._createtime))
        representation.append("%s elapse time: %s" % (_INDENT, self._elapsed_time))
        representation.append("%s status: %s" % (_INDENT, self._status))
        representation.append("%s avd type: %s" % (_INDENT, self._avd_type))
        representation.append("%s display: %s" % (_INDENT, self._display))
        representation.append("%s vnc: 127.0.0.1:%s" % (_INDENT, self._vnc_port))
        representation.append("%s zone: %s" % (_INDENT, self._zone))

        if self._adb_port and self._device_information:
            representation.append("%s adb serial: 127.0.0.1:%s" %
                                  (_INDENT, self._adb_port))
            representation.append("%s product: %s" % (
                _INDENT, self._device_information["product"]))
            representation.append("%s model: %s" % (
                _INDENT, self._device_information["model"]))
            representation.append("%s device: %s" % (
                _INDENT, self._device_information["device"]))
            representation.append("%s transport_id: %s" % (
                _INDENT, self._device_information["transport_id"]))
        else:
            representation.append("%s adb serial: disconnected" % _INDENT)

        return "\n".join(representation)

    def AdbConnected(self):
        """Check AVD adb connected.

        Returns:
            Boolean, True when adb status of AVD is connected.
        """
        if self._adb_port and self._device_information:
            return True
        return False

    @property
    def name(self):
        """Return the instance name."""
        return self._name

    @property
    def fullname(self):
        """Return the instance full name."""
        return self._fullname

    @property
    def ip(self):
        """Return the ip."""
        return self._ip

    @property
    def status(self):
        """Return status."""
        return self._status

    @property
    def display(self):
        """Return display."""
        return self._display

    @property
    def ssh_tunnel_is_connected(self):
        """Return the connect status."""
        return self._ssh_tunnel_is_connected

    @property
    def createtime(self):
        """Return create time."""
        return self._createtime

    @property
    def avd_type(self):
        """Return avd_type."""
        return self._avd_type

    @property
    def avd_flavor(self):
        """Return avd_flavor."""
        return self._avd_flavor

    @property
    def islocal(self):
        """Return if it is a local instance."""
        return self._is_local

    @property
    def adb_port(self):
        """Return adb_port."""
        return self._adb_port

    @property
    def vnc_port(self):
        """Return vnc_port."""
        return self._vnc_port

    @property
    def zone(self):
        """Return zone."""
        return self._zone


class LocalInstance(Instance):
    """Class to store data of local cuttlefish instance."""
    def __init__(self, cf_config_path):
        """Initialize a localInstance object.

        Args:
            cf_config_path: String, path to the cf runtime config.
        """
        self._cf_runtime_cfg = cvd_runtime_config.CvdRuntimeConfig(cf_config_path)
        self._instance_dir = self._cf_runtime_cfg.instance_dir
        self._virtual_disk_paths = self._cf_runtime_cfg.virtual_disk_paths
        self._local_instance_id = int(self._cf_runtime_cfg.instance_id)

        display = _DISPLAY_STRING % {"x_res": self._cf_runtime_cfg.x_res,
                                     "y_res": self._cf_runtime_cfg.y_res,
                                     "dpi": self._cf_runtime_cfg.dpi}
        # TODO(143063678), there's no createtime info in
        # cuttlefish_config.json so far.
        name = GetLocalInstanceName(self._local_instance_id)
        fullname = (_FULL_NAME_STRING %
                    {"device_serial": "127.0.0.1:%s" % self._cf_runtime_cfg.adb_port,
                     "instance_name": name,
                     "elapsed_time": None})
        adb_device = AdbTools(self._cf_runtime_cfg.adb_port)
        device_information = None
        if adb_device.IsAdbConnected():
            device_information = adb_device.device_information

        super(LocalInstance, self).__init__(
            name=name, fullname=fullname, display=display, ip="127.0.0.1",
            status=constants.INS_STATUS_RUNNING,
            adb_port=self._cf_runtime_cfg.adb_port,
            vnc_port=self._cf_runtime_cfg.vnc_port,
            createtime=None, elapsed_time=None, avd_type=constants.TYPE_CF,
            is_local=True, device_information=device_information,
            zone=_LOCAL_ZONE)

    def Summary(self):
        """Return the string that this class is holding."""
        instance_home = "%s instance home: %s" % (_INDENT, self._instance_dir)
        return "%s\n%s" % (super(LocalInstance, self).Summary(), instance_home)

    def CvdStatus(self):
        """check if local instance is active.

        Execute cvd_status cmd to check if it exit without error.

        Returns
            True if instance is active.
        """
        if not self._cf_runtime_cfg.cvd_tools_path:
            logger.debug("No cvd tools path found from config:%s",
                         self._cf_runtime_cfg.config_path)
            return False
        cvd_env = os.environ.copy()
        cvd_env[constants.ENV_CUTTLEFISH_CONFIG_FILE] = self._cf_runtime_cfg.config_path
        cvd_env[constants.ENV_CVD_HOME] = GetLocalInstanceHomeDir(self._local_instance_id)
        cvd_env[constants.ENV_CUTTLEFISH_INSTANCE] = str(self._local_instance_id)
        try:
            cvd_status_cmd = os.path.join(self._cf_runtime_cfg.cvd_tools_path,
                                          _CVD_STATUS_BIN)
            # TODO(b/150575261): Change the cvd home and cvd artifact path to
            #  another place instead of /tmp to prevent from the file not
            #  found exception.
            if not os.path.exists(cvd_status_cmd):
                logger.warning("Cvd tools path doesn't exist:%s", cvd_status_cmd)
                if os.environ.get(constants.ENV_ANDROID_HOST_OUT,
                                  _NO_ANDROID_ENV) in cvd_status_cmd:
                    logger.warning(
                        "Can't find the cvd_status tool (Try lunching a "
                        "cuttlefish target like aosp_cf_x86_phone-userdebug "
                        "and running 'make hosttar' before list/delete local "
                        "instances)")
                return False
            logger.debug("Running cmd[%s] to check cvd status.", cvd_status_cmd)
            process = subprocess.Popen(cvd_status_cmd,
                                       stdin=None,
                                       stdout=subprocess.PIPE,
                                       stderr=subprocess.STDOUT,
                                       env=cvd_env)
            stdout, _ = process.communicate()
            if process.returncode != 0:
                if stdout:
                    logger.debug("Local instance[%s] is not active: %s",
                                 self.name, stdout.strip())
                return False
            return True
        except subprocess.CalledProcessError as cpe:
            logger.error("Failed to run cvd_status: %s", cpe.output)
            return False

    def Delete(self):
        """Execute stop_cvd to stop local cuttlefish instance.

        - We should get the same host tool used to launch cvd to delete instance
        , So get stop_cvd bin from the cvd runtime config.
        - Add CUTTLEFISH_CONFIG_FILE env variable to tell stop_cvd which cvd
        need to be deleted.
        - Stop adb since local instance use the fixed adb port and could be
         reused again soon.
        """
        stop_cvd_cmd = os.path.join(self.cf_runtime_cfg.cvd_tools_path,
                                    constants.CMD_STOP_CVD)
        logger.debug("Running cmd[%s] to delete local cvd", stop_cvd_cmd)
        with open(os.devnull, "w") as dev_null:
            cvd_env = os.environ.copy()
            if self.instance_dir:
                cvd_env[constants.ENV_CUTTLEFISH_CONFIG_FILE] = self._cf_runtime_cfg.config_path
                cvd_env[constants.ENV_CVD_HOME] = GetLocalInstanceHomeDir(
                    self._local_instance_id)
                cvd_env[constants.ENV_CUTTLEFISH_INSTANCE] = str(self._local_instance_id)
            else:
                logger.error("instance_dir is null!! instance[%d] might not be"
                             " deleted", self._local_instance_id)
            subprocess.check_call(
                utils.AddUserGroupsToCmd(stop_cvd_cmd,
                                         constants.LIST_CF_USER_GROUPS),
                stderr=dev_null, stdout=dev_null, shell=True, env=cvd_env)

        adb_cmd = AdbTools(self.adb_port)
        # When relaunch a local instance, we need to pass in retry=True to make
        # sure adb device is completely gone since it will use the same adb port
        adb_cmd.DisconnectAdb(retry=True)

    def GetLock(self):
        """Return the LocalInstanceLock for this object."""
        return GetLocalInstanceLock(self._local_instance_id)

    @property
    def instance_dir(self):
        """Return _instance_dir."""
        return self._instance_dir

    @property
    def instance_id(self):
        """Return _local_instance_id."""
        return self._local_instance_id

    @property
    def virtual_disk_paths(self):
        """Return virtual_disk_paths"""
        return self._virtual_disk_paths

    @property
    def cf_runtime_cfg(self):
        """Return _cf_runtime_cfg"""
        return self._cf_runtime_cfg


class LocalGoldfishInstance(Instance):
    """Class to store data of local goldfish instance."""

    _INSTANCE_NAME_PATTERN = re.compile(
        r"^local-goldfish-instance-(?P<id>\d+)$")
    _CREATION_TIMESTAMP_FILE_NAME = "creation_timestamp.txt"
    _INSTANCE_NAME_FORMAT = "local-goldfish-instance-%(id)s"
    _EMULATOR_DEFAULT_CONSOLE_PORT = 5554
    _GF_ADB_DEVICE_SERIAL = "emulator-%(console_port)s"

    def __init__(self, local_instance_id, avd_flavor=None, create_time=None,
                 x_res=None, y_res=None, dpi=None):
        """Initialize a LocalGoldfishInstance object.

        Args:
            local_instance_id: Integer of instance id.
            avd_flavor: String, the flavor of the virtual device.
            create_time: String, the creation date and time.
            x_res: Integer of x dimension.
            y_res: Integer of y dimension.
            dpi: Integer of dpi.
        """
        self._id = local_instance_id
        # By convention, adb port is console port + 1.
        adb_port = self.console_port + 1

        name = self._INSTANCE_NAME_FORMAT % {"id": local_instance_id}

        elapsed_time = _GetElapsedTime(create_time) if create_time else None

        fullname = _FULL_NAME_STRING % {"device_serial": self.device_serial,
                                        "instance_name": name,
                                        "elapsed_time": elapsed_time}

        if x_res and y_res and dpi:
            display = _DISPLAY_STRING % {"x_res": x_res, "y_res": y_res,
                                         "dpi": dpi}
        else:
            display = "unknown"

        adb = AdbTools(adb_port)
        device_information = (adb.device_information if
                              adb.device_information else None)

        super(LocalGoldfishInstance, self).__init__(
            name=name, fullname=fullname, display=display, ip="127.0.0.1",
            status=None, adb_port=adb_port, avd_type=constants.TYPE_GF,
            createtime=create_time, elapsed_time=elapsed_time,
            avd_flavor=avd_flavor, is_local=True,
            device_information=device_information)

    @staticmethod
    def _GetInstanceDirRoot():
        """Return the root directory of all instance directories."""
        return os.path.join(tempfile.gettempdir(), "acloud_gf_temp")

    @property
    def console_port(self):
        """Return the console port as an integer"""
        # Emulator requires the console port to be an even number.
        return self._EMULATOR_DEFAULT_CONSOLE_PORT + (self._id - 1) * 2

    @property
    def device_serial(self):
        """Return the serial number that contains the console port."""
        return self._GF_ADB_DEVICE_SERIAL % {"console_port": self.console_port}

    @property
    def instance_dir(self):
        """Return the path to instance directory."""
        return os.path.join(self._GetInstanceDirRoot(),
                            self._INSTANCE_NAME_FORMAT % {"id": self._id})

    @property
    def creation_timestamp_path(self):
        """Return the file path containing the creation timestamp."""
        return os.path.join(self.instance_dir,
                            self._CREATION_TIMESTAMP_FILE_NAME)

    def WriteCreationTimestamp(self):
        """Write creation timestamp to file."""
        with open(self.creation_timestamp_path, "w") as timestamp_file:
            timestamp_file.write(str(_GetCurrentLocalTime()))

    def DeleteCreationTimestamp(self, ignore_errors):
        """Delete the creation timestamp file.

        Args:
            ignore_errors: Boolean, whether to ignore the errors.

        Raises:
            OSError if fails to delete the file.
        """
        try:
            os.remove(self.creation_timestamp_path)
        except OSError as e:
            if not ignore_errors:
                raise
            logger.warning("Can't delete creation timestamp: %s", e)

    @classmethod
    def GetExistingInstances(cls):
        """Get a list of instances that have creation timestamp files."""
        instance_root = cls._GetInstanceDirRoot()
        if not os.path.isdir(instance_root):
            return []

        instances = []
        for name in os.listdir(instance_root):
            match = cls._INSTANCE_NAME_PATTERN.match(name)
            timestamp_path = os.path.join(instance_root, name,
                                          cls._CREATION_TIMESTAMP_FILE_NAME)
            if match and os.path.isfile(timestamp_path):
                instance_id = int(match.group("id"))
                with open(timestamp_path, "r") as timestamp_file:
                    timestamp = timestamp_file.read().strip()
                instances.append(LocalGoldfishInstance(instance_id,
                                                       create_time=timestamp))
        return instances


class RemoteInstance(Instance):
    """Class to store data of remote instance."""

    # pylint: disable=too-many-locals
    def __init__(self, gce_instance):
        """Process the args into class vars.

        RemoteInstace initialized by gce dict object. We parse the required data
        from gce_instance to local variables.
        Reference:
        https://cloud.google.com/compute/docs/reference/rest/v1/instances/get

        We also gather more details on client side including the forwarding adb
        port and vnc port which will be used to determine the status of ssh
        tunnel connection.

        The status of gce instance will be displayed in _fullname property:
        - Connected: If gce instance and ssh tunnel and adb connection are all
         active.
        - No connected: If ssh tunnel or adb connection is not found.
        - Terminated: If we can't retrieve the public ip from gce instance.

        Args:
            gce_instance: dict object queried from gce.
        """
        name = gce_instance.get(constants.INS_KEY_NAME)

        create_time = gce_instance.get(constants.INS_KEY_CREATETIME)
        elapsed_time = _GetElapsedTime(create_time)
        status = gce_instance.get(constants.INS_KEY_STATUS)
        zone = self._GetZoneName(gce_instance.get(constants.INS_KEY_ZONE))

        ip = None
        for network_interface in gce_instance.get("networkInterfaces"):
            for access_config in network_interface.get("accessConfigs"):
                ip = access_config.get("natIP")

        # Get metadata
        display = None
        avd_type = None
        avd_flavor = None
        for metadata in gce_instance.get("metadata", {}).get("items", []):
            key = metadata["key"]
            value = metadata["value"]
            if key == constants.INS_KEY_DISPLAY:
                display = value
            elif key == constants.INS_KEY_AVD_TYPE:
                avd_type = value
            elif key == constants.INS_KEY_AVD_FLAVOR:
                avd_flavor = value

        # Find ssl tunnel info.
        adb_port = None
        vnc_port = None
        device_information = None
        if ip:
            forwarded_ports = self.GetAdbVncPortFromSSHTunnel(ip, avd_type)
            adb_port = forwarded_ports.adb_port
            vnc_port = forwarded_ports.vnc_port
            ssh_tunnel_is_connected = adb_port is not None

            adb_device = AdbTools(adb_port)
            if adb_device.IsAdbConnected():
                device_information = adb_device.device_information
                fullname = (_FULL_NAME_STRING %
                            {"device_serial": "127.0.0.1:%d" % adb_port,
                             "instance_name": name,
                             "elapsed_time": elapsed_time})
            else:
                fullname = (_FULL_NAME_STRING %
                            {"device_serial": "not connected",
                             "instance_name": name,
                             "elapsed_time": elapsed_time})
        # If instance is terminated, its ip is None.
        else:
            ssh_tunnel_is_connected = False
            fullname = (_FULL_NAME_STRING %
                        {"device_serial": "terminated",
                         "instance_name": name,
                         "elapsed_time": elapsed_time})

        super(RemoteInstance, self).__init__(
            name=name, fullname=fullname, display=display, ip=ip, status=status,
            adb_port=adb_port, vnc_port=vnc_port,
            ssh_tunnel_is_connected=ssh_tunnel_is_connected,
            createtime=create_time, elapsed_time=elapsed_time, avd_type=avd_type,
            avd_flavor=avd_flavor, is_local=False,
            device_information=device_information,
            zone=zone)

    @staticmethod
    def _GetZoneName(zone_info):
        """Get the zone name from the zone information of gce instance.

        Zone information is like:
        "https://www.googleapis.com/compute/v1/projects/project/zones/us-central1-c"
        We want to get "us-central1-c" as zone name.

        Args:
            zone_info: String, zone information of gce instance.

        Returns:
            Zone name of gce instance. None if zone name can't find.
        """
        zone_match = _RE_ZONE.match(zone_info)
        if zone_match:
            return zone_match.group("zone")

        logger.debug("Can't get zone name from %s.", zone_info)
        return None

    @staticmethod
    def GetAdbVncPortFromSSHTunnel(ip, avd_type):
        """Get forwarding adb and vnc port from ssh tunnel.

        Args:
            ip: String, ip address.
            avd_type: String, the AVD type.

        Returns:
            NamedTuple ForwardedPorts(vnc_port, adb_port) holding the ports
            used in the ssh forwarded call. Both fields are integers.
        """
        if avd_type not in utils.AVD_PORT_DICT:
            return utils.ForwardedPorts(vnc_port=None, adb_port=None)

        default_vnc_port = utils.AVD_PORT_DICT[avd_type].vnc_port
        default_adb_port = utils.AVD_PORT_DICT[avd_type].adb_port
        re_pattern = re.compile(_RE_SSH_TUNNEL_PATTERN %
                                (_RE_GROUP_VNC, default_vnc_port,
                                 _RE_GROUP_ADB, default_adb_port, ip))
        adb_port = None
        vnc_port = None
        process_output = utils.CheckOutput(constants.COMMAND_PS)
        for line in process_output.splitlines():
            match = re_pattern.match(line)
            if match:
                adb_port = int(match.group(_RE_GROUP_ADB))
                vnc_port = int(match.group(_RE_GROUP_VNC))
                break

        logger.debug(("grathering detail for ssh tunnel. "
                      "IP:%s, forwarding (adb:%d, vnc:%d)"), ip, adb_port,
                     vnc_port)

        return utils.ForwardedPorts(vnc_port=vnc_port, adb_port=adb_port)
