#!/usr/bin/env python
# Copyright 2020 The Fuchsia 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 os


class Namespace(object):
    """Represents the package filesystem namespace for a fuzzer.

    The fuzzer executable's view of the filesystem is different from the
    device's. When the fuzzer is run as a component, certain paths get mapped
    to certain locations in the fuzzer's namespace. This object represents and
    encapsulates that mapping for code that needs to move data between the
    device and the host.

    Parameter names are chosen according to the following convetions:
        abspath         An global, absolute path outside any namespace.
        data_path       Path within a namespace mapping to mutable storage.
        resouce_path    Path within a namespace mapping to package resources.
        relpath         A path fragment relative to one of the other 3 contexts.

    e.g. Given relpath = "foo":
        data_path(relpath)          -> "data/foo"
        resouce_path(relpath)       -> "pkg/data/foo"
        abspath(data_path(relpath)) -> "/some/path/accesssible/by/scp/foo"

    Attributes:
        fuzzer:         The Fuzzer corresponding to this object.
        device:         Alias for fuzzer.device.
  """

    def __init__(self, fuzzer):
        self._fuzzer = fuzzer

    @property
    def fuzzer(self):
        """The associated Fuzzer object."""
        return self._fuzzer

    @property
    def device(self):
        """Alias for fuzzer.device."""
        return self.fuzzer.device

    @property
    def host(self):
        """Alias for fuzzer.host."""
        return self.fuzzer.host

    # Unit test utilities

    def base_abspath(self, relpath=''):
        """Absolute package path when package is included in the base image."""
        base = '/pkgfs/packages/{}/0'.format(self.fuzzer.package)
        return '{}/{}'.format(base, relpath) if relpath else base

    def data_abspath(self, relpath):
        """Absolute path to mutable data."""
        base = '/data/r/sys/fuchsia.com:{}:0#meta:{}.cmx'.format(
            self.fuzzer.package, self.fuzzer.executable)
        if relpath.startswith(base):
            return relpath
        elif relpath.startswith('/'):
            self.host.error('Not a data path: {}'.format(relpath))
        elif relpath.startswith(self.data()):
            relpath = relpath[len(self.data()):]
        return '{}/{}'.format(base, relpath)

    def resource_abspath(self, relpath):
        """Absolute path to a package resource."""
        base = '{}/data/{}'.format(
            self.fuzzer.package_path, self.fuzzer.executable)
        if relpath.startswith(base):
            return relpath
        elif relpath.startswith('/'):
            self.host.error('Not a resource path: {}'.format(relpath))
        elif relpath.startswith(self.resource()):
            relpath = relpath[len(self.resource()):]
        return '{}/{}'.format(base, relpath)

    def abspath(self, nspath):
        if nspath.startswith(self.data()):
            return self.data_abspath(nspath)
        elif nspath.startswith(self.resource()):
            return self.resource_abspath(nspath)
        else:
            self.host.error('Not a data or resource path: {}'.format(nspath))

    def data(self, relpath=''):
        """Returns a namespace path to package data."""
        base = 'data'
        if relpath.startswith('base/'):
            return relpath
        return '{}/{}'.format(base, relpath)

    def resource(self, relpath=''):
        """Returns a namespace path to package resources."""
        base = 'pkg/data/{}'.format(self.fuzzer.executable)
        if relpath.startswith(base):
            return relpath
        return '{}/{}'.format(base, relpath)

    def ls(self, nspath):
        """Lists a directory in the namespace."""
        return self.device.ls(self.abspath(nspath))

    def mkdir(self, data_path):
        """Makes a directory in the namespace."""
        self.device.mkdir(self.data_abspath(data_path))

    def remove(self, data_path, recursive=False):
        """Removes files or directories from the namespace."""
        return self.device.remove(self.data_abspath(data_path), recursive)

    def fetch(self, pathname, *args):
        """Copies from the namespace to the path given by the first argument."""
        args = [self.abspath(arg) for arg in args]
        self.device.fetch(pathname, *args)

    def store(self, data_path, *args):
        """Copies to the namespace path given by the first argument."""
        abspath = self.data_abspath(data_path)
        pathnames = self.device.store(abspath, *args)
        relpaths = [os.path.basename(pathname) for pathname in pathnames]
        return [self.data(relpath) for relpath in relpaths]
