#
# Copyright (C) 2016 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.


"""This file provides all ACL related parsing and behavior."""


import os
import re
import struct


from project import common
from selinux import file_context


class FileAcl(object):
    DEFAULTS = {
        'USER': '1000',
        'GROUP': '1000',
        'SELABEL': '',
        'PERMISSIONS': '0400',
        'CAPABILITIES': '0'
    }

    def __init__(self, copy):
        self._origin = common.Origin()
        self._copy = copy
        # For now, we default to system.
        self._user = self.DEFAULTS['USER']
        self._group = self.DEFAULTS['GROUP']
        self._selabel = self.DEFAULTS['SELABEL']
        self._perms = self.DEFAULTS['PERMISSIONS']
        self._fcaps = self.DEFAULTS['CAPABILITIES']
        # For packs which wrap a Android build, we will often
        # want to just use the build systems default values.
        # When this is False, fs_config and file_context will
        # return empty.
        self._override_build = True
        # TODO(wad): add more types (b/27848879).
        self._file_type = file_context.FILE_TYPE_FILE
        default_acl = None
        if (copy is not None and
                copy.pack is not None and
                copy.pack.defaults is not None):
            default_acl = copy.pack.defaults.acl
        if default_acl is not None:
            self._user = default_acl.user
            self._group = default_acl.group
            self._selabel = default_acl.selabel
            self._perms = default_acl.perms
            self._fcaps = default_acl.fcaps

    def load(self, ele):
        """Loads the FileAcl from a XML element node (set-acl)."""
        self._origin = ele.origin.copy()
        ele.limit_attribs(['user', 'group', 'selabel', 'perms', 'fcaps'])
        # Since all attributes are optional, we can just pull from the
        # element attrib.
        for key in ele.attrib:
            if ele.attrib[key] not in (None, ''):
                self.__dict__['_{}'.format(key)] = ele.attrib[key]
        if self._perms is not None:
            if not re.match('^0[0-7][0-7][0-7]$', self._perms):
                raise common.LoadErrorWithOrigin(
                    self._origin,
                    '@perms must match ^0[0-7][0-7][0-7]$: {}'.format(
                        self._perms))
        # TODO(wad) Add fcaps content validation.
        if self._fcaps != self.DEFAULTS['CAPABILITIES']:
            raise common.LoadErrorWithOrigin(
                self._origin, '@fcaps support is not yet implemented.')

    @property
    def override_build(self):
        return self._override_build

    @override_build.setter
    def override_build(self, build_def):
        self._override_build = build_def

    @property
    def user(self):
        return self._user

    @user.setter
    def user(self, user):
        # TODO(wad) http://b/27564772
        try:
            self._user = int(user)
        except TypeError:
            raise ValueError('user must be numeric: {}'.format(user))

    @property
    def group(self):
        return self._group

    @group.setter
    def group(self, group):
        # TODO(wad) http://b/27564772
        try:
            self._group = int(group)
        except TypeError:
            raise ValueError('group must be numeric: {}'.format(group))

    @property
    def perms(self):
        return self._perms

    @perms.setter
    def perms(self, perms):
        try:
            self._perms = oct(int(perms, 8))
        except TypeError:
            raise ValueError('perms must be octal: {}'.format(perms))

    @property
    def selabel(self):
        return self._selabel

    @selabel.setter
    def selabel(self, selabel):
        self._selabel = selabel

    @property
    def fcaps(self):
        return self._fcaps

    @fcaps.setter
    def fcaps(self, fcaps):
        self._fcaps = fcaps

    @property
    def copy(self):
        return self._copy

    @copy.setter
    def copy(self, cpy):
        self._copy = cpy

    @property
    def file_type(self):
        return self._file_type

    @file_type.setter
    def file_type(self, ftype):
        if ftype not in file_context.FILE_TYPE.keys():
            raise ValueError('ftype must be one of {}: {}'.format(
                file_context.FILE_TYPE.keys(), ftype))
        self._file_type = ftype

    def file_context(self, path=None, ftype=None):
        """Builds a ASCII SELinux file context entry for the given ACL.

        If the ACL is applied to a GLOB, then path and ftype
        should be applied or the glob will be written into the
        file_context.
        """
        if self.override_build == False:
            return ''
        path = path or self._copy.dst
        if not os.path.isabs(path):
            path = os.path.sep + path
        ftype = ftype or file_context.FILE_TYPE[self._file_type]
        return '{} {} {}'.format(path, ftype, self._selabel)

    def fs_config(self, path=None, binary=False):
        """Returns the fs_config entry in ASCII or binary format.

        Args:
            path: Optionally override the copy destination.
            binary: If True, returns the binary fs_config format.
                If False, returns the ASCII fs_config format.

        Note for callers: binary fs_config files will be evaluated
        in first match order so it is important to use more specific
        paths first.
        """
        if self.override_build == False:
            return ''
        path = path or self._copy.dst
        if path.startswith(os.path.sep):
            path = path.lstrip('/')
        if binary:
            # https://android.googlesource.com/platform/system/core/+/master/libcutils/fs_config.c#45
            # struct fs_path_config_from_file {
            #     uint16_t length; /* header plus prefix */
            #     uint16_t mode;
            #     uint16_t uid;
            #     uint16_t gid
            #     uint64_t capabilities;
            #     char prefix[];
            # }   __attribute__((__aligned__(sizeof(uint64_t))));
            path_len = len(path) + 1  # Terminating NUL is required.
            total_len = 16 + path_len
            # The on-disk format is little endian byte order.
            entry = struct.pack(
                '<HHHHQ{}s'.format(path_len), total_len,
                int(self._perms, 8), int(self._user),
                int(self._group), int(self._fcaps), path)
            return entry
        return '{} {} {} {} capabilities={}'.format(
            path, self._user, self._group, self._perms, self._fcaps)

    def __repr__(self):
        return ('<set-acl user="{}" group="{}" selabel="{}" '
                'perms="{}" fcaps="{}"/>'.format(
                    self._user or '', self._group or '', self._selabel or '',
                    self._perms or '', self._fcaps or ''))
