/*
 * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Oracle nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * This source code is provided to illustrate the usage of a given feature
 * or technique and has been deliberately simplified. Additional steps
 * required for a production-quality application, such as security checks,
 * input validation and proper error handling, might not be present in
 * this sample code.
 */


import java.nio.file.*;
import java.nio.file.attribute.*;
import java.io.IOException;
import java.util.*;
import java.util.regex.Pattern;

/**
 * Sample utility for editing a file's ACL.
 */

public class AclEdit {

    // parse string as list of ACE permissions separated by /
    static Set<AclEntryPermission> parsePermissions(String permsString) {
        Set<AclEntryPermission> perms = new HashSet<AclEntryPermission>();
        String[] result = permsString.split("/");
        for (String s : result) {
            if (s.equals(""))
                continue;
            try {
                perms.add(AclEntryPermission.valueOf(s.toUpperCase()));
            } catch (IllegalArgumentException x) {
                System.err.format("Invalid permission '%s'\n", s);
                System.exit(-1);
            }
        }
        return perms;
    }

    // parse string as list of ACE flags separated by /
    static Set<AclEntryFlag> parseFlags(String flagsString) {
        Set<AclEntryFlag> flags = new HashSet<AclEntryFlag>();
        String[] result = flagsString.split("/");
        for (String s : result) {
            if (s.equals(""))
                continue;
            try {
                flags.add(AclEntryFlag.valueOf(s.toUpperCase()));
            } catch (IllegalArgumentException x) {
                System.err.format("Invalid flag '%s'\n", s);
                System.exit(-1);
            }
        }
        return flags;
    }

    // parse ACE type
    static AclEntryType parseType(String typeString) {
        // FIXME: support audit and alarm types in the future
        if (typeString.equalsIgnoreCase("allow"))
            return AclEntryType.ALLOW;
        if (typeString.equalsIgnoreCase("deny"))
            return AclEntryType.DENY;
        System.err.format("Invalid type '%s'\n", typeString);
        System.exit(-1);
        return null;    // keep compiler happy
    }

    /**
     * Parse string of the form:
     *   [user|group:]<username|groupname>:<perms>[:flags]:<allow|deny>
     */
    static AclEntry parseAceString(String s,
                                   UserPrincipalLookupService lookupService)
    {
        String[] result = s.split(":");

        // must have at least 3 components (username:perms:type)
        if (result.length < 3)
            usage();

        int index = 0;
        int remaining = result.length;

        // optional first component can indicate user or group type
        boolean isGroup = false;
        if (result[index].equalsIgnoreCase("user") ||
            result[index].equalsIgnoreCase("group"))
        {
            if (--remaining < 3)
                usage();
            isGroup = result[index++].equalsIgnoreCase("group");
        }

        // user and permissions required
        String userString = result[index++]; remaining--;
        String permsString = result[index++]; remaining--;

        // flags are optional
        String flagsString = "";
        String typeString = null;
        if (remaining == 1) {
            typeString = result[index++];
        } else {
            if (remaining == 2) {
                flagsString = result[index++];
                typeString = result[index++];
            } else {
                usage();
            }
        }

        // lookup UserPrincipal
        UserPrincipal user = null;
        try {
            user = (isGroup) ?
                lookupService.lookupPrincipalByGroupName(userString) :
                lookupService.lookupPrincipalByName(userString);
        } catch (UserPrincipalNotFoundException x) {
            System.err.format("Invalid %s '%s'\n",
                ((isGroup) ? "group" : "user"),
                userString);
            System.exit(-1);
        } catch (IOException x) {
            System.err.format("Lookup of '%s' failed: %s\n", userString, x);
            System.exit(-1);
        }

        // map string representation of permissions, flags, and type
        Set<AclEntryPermission> perms = parsePermissions(permsString);
        Set<AclEntryFlag> flags = parseFlags(flagsString);
        AclEntryType type = parseType(typeString);

        // build the ACL entry
        return AclEntry.newBuilder()
            .setType(type)
            .setPrincipal(user)
            .setPermissions(perms).setFlags(flags).build();
    }

    static void usage() {
        System.err.println("usage: java AclEdit [ACL-operation] file");
        System.err.println("");
        System.err.println("Example 1: Prepends access control entry to the begining of the myfile's ACL");
        System.err.println("       java AclEdit A+alice:read_data/read_attributes:allow myfile");
        System.err.println("");
        System.err.println("Example 2: Remove the entry at index 6 of myfile's ACL");
        System.err.println("       java AclEdit A6- myfile");
        System.err.println("");
        System.err.println("Example 3: Replace the entry at index 2 of myfile's ACL");
        System.err.println("       java AclEdit A2=bob:write_data/append_data:deny myfile");
        System.exit(-1);
    }

    static enum Action {
        PRINT,
        ADD,
        REMOVE,
        REPLACE;
    }

    /**
     * Main class: parses arguments and prints or edits ACL
     */
    public static void main(String[] args) throws IOException {
        Action action = null;
        int index = -1;
        String entryString = null;

        // parse arguments
        if (args.length < 1 || args[0].equals("-help") || args[0].equals("-?"))
            usage();

        if (args.length == 1) {
            action = Action.PRINT;
        } else {
            String s = args[0];

            // A[index]+entry
            if (Pattern.matches("^A[0-9]*\\+.*", s)) {
                String[] result = s.split("\\+", 2);
                if (result.length == 2) {
                    if (result[0].length() < 2) {
                        index = 0;
                    } else {
                        index = Integer.parseInt(result[0].substring(1));
                    }
                    entryString = result[1];
                    action = Action.ADD;
                }
            }

            // Aindex-
            if (Pattern.matches("^A[0-9]+\\-", s)) {
                String[] result = s.split("\\-", 2);
                if (result.length == 2) {
                    index = Integer.parseInt(result[0].substring(1));
                    entryString = result[1];
                    action = Action.REMOVE;
                }
            }

            // Aindex=entry
            if (Pattern.matches("^A[0-9]+=.*", s)) {
                String[] result = s.split("=", 2);
                if (result.length == 2) {
                    index = Integer.parseInt(result[0].substring(1));
                    entryString = result[1];
                    action = Action.REPLACE;
                }
            }
        }
        if (action == null)
            usage();

        int fileArg = (action == Action.PRINT) ? 0 : 1;
        Path file = Paths.get(args[fileArg]);

        // read file's ACL
        AclFileAttributeView view =
            Files.getFileAttributeView(file, AclFileAttributeView.class);
        if (view == null) {
            System.err.println("ACLs not supported on this platform");
            System.exit(-1);
        }
        List<AclEntry> acl = view.getAcl();

        switch (action) {
            // print ACL
            case PRINT : {
                for (int i=0; i<acl.size(); i++) {
                    System.out.format("%5d: %s\n", i, acl.get(i));
                }
                break;
            }

            // add ACE to existing ACL
            case ADD: {
                AclEntry entry = parseAceString(entryString, file
                    .getFileSystem().getUserPrincipalLookupService());
                if (index >= acl.size()) {
                    acl.add(entry);
                } else {
                    acl.add(index, entry);
                }
                view.setAcl(acl);
                break;
            }

            // remove ACE
            case REMOVE: {
                if (index >= acl.size()) {
                    System.err.format("Index '%d' is invalid", index);
                    System.exit(-1);
                }
                acl.remove(index);
                view.setAcl(acl);
                break;
            }

            // replace ACE
            case REPLACE: {
                if (index >= acl.size()) {
                    System.err.format("Index '%d' is invalid", index);
                    System.exit(-1);
                }
                AclEntry entry = parseAceString(entryString, file
                    .getFileSystem().getUserPrincipalLookupService());
                acl.set(index, entry);
                view.setAcl(acl);
                break;
            }
        }
    }
}
