/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */
package org.apache.logging.log4j.core.appender.rolling.action;

import org.apache.logging.log4j.core.Core;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
import org.apache.logging.log4j.core.lookup.StrSubstitutor;
import org.apache.logging.log4j.core.util.FileUtils;
import org.apache.logging.log4j.plugins.Plugin;
import org.apache.logging.log4j.plugins.PluginBuilderAttribute;
import org.apache.logging.log4j.plugins.PluginElement;
import org.apache.logging.log4j.plugins.PluginFactory;
import org.apache.logging.log4j.plugins.validation.constraints.Required;
import org.apache.logging.log4j.util.Strings;

import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileOwnerAttributeView;
import java.nio.file.attribute.PosixFileAttributeView;
import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.attribute.PosixFilePermissions;
import java.util.List;
import java.util.Set;

/**
 * File posix attribute view action.
 * 
 * Allow to define file permissions, user and group for log files on posix supported OS.
 */
@Plugin(name = "PosixViewAttribute", category = Core.CATEGORY_NAME, printObject = true)
public class PosixViewAttributeAction extends AbstractPathAction {
    
    /**
     * File permissions.
     */
    private final Set<PosixFilePermission> filePermissions;

    /**
     * File owner.
     */
    private final String fileOwner;

    /**
     * File group.
     */
    private final String fileGroup;

    private PosixViewAttributeAction(final String basePath, final boolean followSymbolicLinks,
            final int maxDepth, final PathCondition[] pathConditions, final StrSubstitutor subst,
            final Set<PosixFilePermission> filePermissions,
            final String fileOwner, final String fileGroup) {
        super(basePath, followSymbolicLinks, maxDepth, pathConditions, subst);
        this.filePermissions = filePermissions;
        this.fileOwner = fileOwner;
        this.fileGroup = fileGroup;
    }

    @PluginFactory
    public static Builder newBuilder() {
        return new Builder();
    }

    /**
     * Builder for the posix view attribute action.
     */
    public static class Builder implements org.apache.logging.log4j.plugins.util.Builder<PosixViewAttributeAction> {

        @PluginConfiguration
        private Configuration configuration;
        
        private StrSubstitutor subst;

        @PluginBuilderAttribute
        @Required(message = "No base path provided")
        private String basePath;

        @PluginBuilderAttribute
        private boolean followLinks = false;

        @PluginBuilderAttribute
        private int maxDepth = 1;

        @PluginElement("PathConditions")
        private PathCondition[] pathConditions;

        @PluginBuilderAttribute(value = "filePermissions")
        private String filePermissionsString;

        private Set<PosixFilePermission> filePermissions;

        @PluginBuilderAttribute
        private String fileOwner;

        @PluginBuilderAttribute
        private String fileGroup;

        @Override
        public PosixViewAttributeAction build() {
            if (Strings.isEmpty(basePath)) {
                LOGGER.error("Posix file attribute view action not valid because base path is empty.");
                return null;
            }

            if (filePermissions == null && Strings.isEmpty(filePermissionsString)
                        && Strings.isEmpty(fileOwner) && Strings.isEmpty(fileGroup)) {
                LOGGER.error("Posix file attribute view not valid because nor permissions, user or group defined.");
                return null;
            }

            if (!FileUtils.isFilePosixAttributeViewSupported()) {
                LOGGER.warn("Posix file attribute view defined but it is not supported by this files system.");
                return null;
            }

            return new PosixViewAttributeAction(basePath, followLinks, maxDepth, pathConditions,
                    subst != null ? subst : configuration.getStrSubstitutor(),
                    filePermissions != null ? filePermissions :
                                filePermissionsString != null ? PosixFilePermissions.fromString(filePermissionsString) : null,
                    fileOwner,
                    fileGroup);
        }

        /**
         * Define required configuration, used to retrieve string substituter.
         *
         * @param configuration {@link AbstractPathAction#getStrSubstitutor()}
         * @return This builder
         */
        public Builder setConfiguration(final Configuration configuration) {
            this.configuration = configuration;
            return this;
        }

        /**
         * Define string substituter.
         *
         * @param subst {@link AbstractPathAction#getStrSubstitutor()}
         * @return This builder
         */
        public Builder setSubst(final StrSubstitutor subst) {
            this.subst = subst;
            return this;
        }

        /**
         * Define base path to apply condition before execute posix file attribute action.
         * @param basePath {@link AbstractPathAction#getBasePath()}
         * @return This builder
         */
        public Builder setBasePath(final String basePath) {
            this.basePath = basePath;
            return this;
        }

        /**
         * True to allow synonyms links during search of eligible files.
         * @param followLinks Follow synonyms links
         * @return This builder
         */
        public Builder setFollowLinks(final boolean followLinks) {
            this.followLinks = followLinks;
            return this;
        }

        /**
         * Define max folder depth to search for eligible files to apply posix attribute view.
         * @param maxDepth Max search depth 
         * @return This builder
         */
        public Builder setMaxDepth(final int maxDepth) {
            this.maxDepth = maxDepth;
            return this;
        }

        /**
         * Define path conditions to filter files in {@link PosixViewAttributeAction#getBasePath()}.
         *
         * @param pathConditions {@link AbstractPathAction#getPathConditions()}
         * @return This builder
         */
        public Builder setPathConditions(final PathCondition[] pathConditions) {
            this.pathConditions = pathConditions;
            return this;
        }

        /**
         * Define file permissions in posix format to apply during action execution eligible files.
         *
         * Example:
         * <p>rw-rw-rw
         * <p>r--r--r--
         * @param filePermissionsString Permissions to apply
         * @return This builder
         */
        public Builder setFilePermissionsString(final String filePermissionsString) {
            this.filePermissionsString = filePermissionsString;
            return this;
        }

        /**
         * Define file permissions to apply during action execution eligible files.
         * @param filePermissions Permissions to apply
         * @return This builder
         */
        public Builder setFilePermissions(final Set<PosixFilePermission> filePermissions) {
            this.filePermissions = filePermissions;
            return this;
        }

        /**
         * Define file owner to apply during action execution eligible files.
         * @param fileOwner File owner
         * @return This builder
         */
        public Builder setFileOwner(final String fileOwner) {
            this.fileOwner = fileOwner;
            return this;
        }

        /**
         * Define file group to apply during action execution eligible files.
         * @param fileGroup File group
         * @return This builder
         */
        public Builder setFileGroup(final String fileGroup) {
            this.fileGroup = fileGroup;
            return this;
        }
    }

    @Override
    protected FileVisitor<Path> createFileVisitor(final Path basePath,
            final List<PathCondition> conditions) {
        return new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException {
                for (final PathCondition pathFilter : conditions) {
                    final Path relative = basePath.relativize(file);
                    if (!pathFilter.accept(basePath, relative, attrs)) {
                        LOGGER.trace("Not defining posix attribute base={}, relative={}", basePath, relative);
                        return FileVisitResult.CONTINUE;
                    }
                }
                FileUtils.defineFilePosixAttributeView(file, filePermissions, fileOwner, fileGroup);
                return FileVisitResult.CONTINUE;
            }
        };
    }

    /**
     * Returns posix file permissions if defined and the OS supports posix file attribute,
     * null otherwise.
     * @return File posix permissions
     * @see PosixFileAttributeView
     */
    public Set<PosixFilePermission> getFilePermissions() {
        return filePermissions;
    }
    
    /**
     * Returns file owner if defined and the OS supports owner file attribute view,
     * null otherwise. 
     * @return File owner
     * @see FileOwnerAttributeView
     */
    public String getFileOwner() {
        return fileOwner;
    }

    /**
     * Returns file group if defined and the OS supports posix/group file attribute view,
     * null otherwise. 
     * @return File group
     * @see PosixFileAttributeView
     */
    public String getFileGroup() {
        return fileGroup;
    }

    @Override
    public String toString() {
        return "PosixViewAttributeAction [filePermissions=" + filePermissions + ", fileOwner="
                + fileOwner + ", fileGroup=" + fileGroup + ", getBasePath()=" + getBasePath()
                + ", getMaxDepth()=" + getMaxDepth() + ", getPathConditions()="
                + getPathConditions() + "]";
    }

}
