/*
 * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.nio.fs;

import java.nio.file.attribute.*;
import java.util.Map;
import java.io.IOException;
import sun.misc.Unsafe;

import static sun.nio.fs.UnixNativeDispatcher.*;
import static sun.nio.fs.UnixConstants.*;

/**
 * Linux implementation of DosFileAttributeView for use on file systems such
 * as ext3 that have extended attributes enabled and SAMBA configured to store
 * DOS attributes.
 */

class LinuxDosFileAttributeView
    extends UnixFileAttributeViews.Basic implements DosFileAttributeView
{
    private static final Unsafe unsafe = Unsafe.getUnsafe();

    private static final String READONLY_NAME = "readonly";
    private static final String ARCHIVE_NAME = "archive";
    private static final String SYSTEM_NAME = "system";
    private static final String HIDDEN_NAME = "hidden";

    private static final String DOS_XATTR_NAME = "user.DOSATTRIB";
    private static final byte[] DOS_XATTR_NAME_AS_BYTES = DOS_XATTR_NAME.getBytes();

    private static final int DOS_XATTR_READONLY = 0x01;
    private static final int DOS_XATTR_HIDDEN   = 0x02;
    private static final int DOS_XATTR_SYSTEM   = 0x04;
    private static final int DOS_XATTR_ARCHIVE  = 0x20;

    LinuxDosFileAttributeView(UnixPath file, boolean followLinks) {
        super(file, followLinks);
    }

    @Override
    public String name() {
        return "dos";
    }

    @Override
    public Object getAttribute(String attribute) throws IOException {
        if (attribute.equals(READONLY_NAME))
            return readAttributes().isReadOnly();
        if (attribute.equals(ARCHIVE_NAME))
            return readAttributes().isArchive();
        if (attribute.equals(SYSTEM_NAME))
            return readAttributes().isSystem();
        if (attribute.equals(HIDDEN_NAME))
            return readAttributes().isHidden();
        return super.getAttribute(attribute);
    }

    @Override
    public void setAttribute(String attribute, Object value)
        throws IOException
    {
        if (attribute.equals(READONLY_NAME)) {
            setReadOnly((Boolean)value);
            return;
        }
        if (attribute.equals(ARCHIVE_NAME)) {
            setArchive((Boolean)value);
            return;
        }
        if (attribute.equals(SYSTEM_NAME)) {
            setSystem((Boolean)value);
            return;
        }
        if (attribute.equals(HIDDEN_NAME)) {
            setHidden((Boolean)value);
            return;
        }
        super.setAttribute(attribute, value);
    }

    @Override
    public Map<String,?> readAttributes(String[] attributes)
        throws IOException
    {
        AttributesBuilder builder = AttributesBuilder.create(attributes);
        DosFileAttributes attrs = readAttributes();
        addBasicAttributesToBuilder(attrs, builder);
        if (builder.match(READONLY_NAME))
            builder.add(READONLY_NAME, attrs.isReadOnly());
        if (builder.match(ARCHIVE_NAME))
            builder.add(ARCHIVE_NAME, attrs.isArchive());
        if (builder.match(SYSTEM_NAME))
            builder.add(SYSTEM_NAME, attrs.isSystem());
        if (builder.match(HIDDEN_NAME))
            builder.add(HIDDEN_NAME, attrs.isHidden());
        return builder.unmodifiableMap();
    }

    @Override
    public DosFileAttributes readAttributes() throws IOException {
        file.checkRead();

        int fd = file.openForAttributeAccess(followLinks);
        try {
             final UnixFileAttributes attrs = UnixFileAttributes.get(fd);
             final int dosAttribute = getDosAttribute(fd);

             return new DosFileAttributes() {
                @Override
                public FileTime lastModifiedTime() {
                    return attrs.lastModifiedTime();
                }
                @Override
                public FileTime lastAccessTime() {
                    return attrs.lastAccessTime();
                }
                @Override
                public FileTime creationTime() {
                    return attrs.creationTime();
                }
                @Override
                public boolean isRegularFile() {
                    return attrs.isRegularFile();
                }
                @Override
                public boolean isDirectory() {
                    return attrs.isDirectory();
                }
                @Override
                public boolean isSymbolicLink() {
                    return attrs.isSymbolicLink();
                }
                @Override
                public boolean isOther() {
                    return attrs.isOther();
                }
                @Override
                public long size() {
                    return attrs.size();
                }
                @Override
                public Object fileKey() {
                    return attrs.fileKey();
                }
                @Override
                public boolean isReadOnly() {
                    return (dosAttribute & DOS_XATTR_READONLY) != 0;
                }
                @Override
                public boolean isHidden() {
                    return (dosAttribute & DOS_XATTR_HIDDEN) != 0;
                }
                @Override
                public boolean isArchive() {
                    return (dosAttribute & DOS_XATTR_ARCHIVE) != 0;
                }
                @Override
                public boolean isSystem() {
                    return (dosAttribute & DOS_XATTR_SYSTEM) != 0;
                }
             };

        } catch (UnixException x) {
            x.rethrowAsIOException(file);
            return null;    // keep compiler happy
        } finally {
            close(fd);
        }
    }

    @Override
    public void setReadOnly(boolean value) throws IOException {
        updateDosAttribute(DOS_XATTR_READONLY, value);
    }

    @Override
    public void setHidden(boolean value) throws IOException {
        updateDosAttribute(DOS_XATTR_HIDDEN, value);
    }

    @Override
    public void setArchive(boolean value) throws IOException {
        updateDosAttribute(DOS_XATTR_ARCHIVE, value);
    }

    @Override
    public void setSystem(boolean value) throws IOException {
        updateDosAttribute(DOS_XATTR_SYSTEM, value);
    }

    /**
     * Reads the value of the user.DOSATTRIB extended attribute
     */
    private int getDosAttribute(int fd) throws UnixException {
        final int size = 24;

        NativeBuffer buffer = NativeBuffers.getNativeBuffer(size);
        try {
            int len = LinuxNativeDispatcher
                .fgetxattr(fd, DOS_XATTR_NAME_AS_BYTES, buffer.address(), size);

            if (len > 0) {
                // ignore null terminator
                if (unsafe.getByte(buffer.address()+len-1) == 0)
                    len--;

                // convert to String and parse
                byte[] buf = new byte[len];
                unsafe.copyMemory(null, buffer.address(), buf,
                    Unsafe.ARRAY_BYTE_BASE_OFFSET, len);
                String value = new String(buf); // platform encoding

                // should be something like 0x20
                if (value.length() >= 3 && value.startsWith("0x")) {
                    try {
                        return Integer.parseInt(value.substring(2), 16);
                    } catch (NumberFormatException x) {
                        // ignore
                    }
                }
            }
            throw new UnixException("Value of " + DOS_XATTR_NAME + " attribute is invalid");
        } catch (UnixException x) {
            // default value when attribute does not exist
            if (x.errno() == ENODATA)
                return 0;
            throw x;
        } finally {
            buffer.release();
        }
    }

    /**
     * Updates the value of the user.DOSATTRIB extended attribute
     */
    private void updateDosAttribute(int flag, boolean enable) throws IOException {
        file.checkWrite();

        int fd = file.openForAttributeAccess(followLinks);
        try {
            int oldValue = getDosAttribute(fd);
            int newValue = oldValue;
            if (enable) {
                newValue |= flag;
            } else {
                newValue &= ~flag;
            }
            if (newValue != oldValue) {
                byte[] value = ("0x" + Integer.toHexString(newValue)).getBytes();
                NativeBuffer buffer = NativeBuffers.asNativeBuffer(value);
                try {
                    LinuxNativeDispatcher.fsetxattr(fd, DOS_XATTR_NAME_AS_BYTES,
                        buffer.address(), value.length+1);
                } finally {
                    buffer.release();
                }
            }
        } catch (UnixException x) {
            x.rethrowAsIOException(file);
        } finally {
            close(fd);
        }
    }
}
