#!/usr/bin/env python3.8
# 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."""
        if self.fuzzer.is_test:
            if self.fuzzer.realm_label:
                base = '/data/r/sys/r/{}/fuchsia.com:{}:0#meta:{}_test.cmx'.format(
                    self.fuzzer.realm_label, self.fuzzer.package,
                    self.fuzzer.executable)
            else:
                base = '/data/r/sys/fuchsia.com:{}:0#meta:{}_test.cmx'.format(
                    self.fuzzer.package, self.fuzzer.executable)
        else:
            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 = self.fuzzer.package_path + '/data'
        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'
        if relpath.startswith(base):
            return relpath
        return '{}/{}'.format(base, relpath.lstrip('/'))

    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]
