/*
 * 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.jackrabbit.oak.jcr.session;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Sets.newTreeSet;
import static org.apache.jackrabbit.api.stats.RepositoryStatistics.Type.SESSION_COUNT;
import static org.apache.jackrabbit.oak.commons.PathUtils.getParentPath;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.AccessControlException;
import java.util.Collections;
import java.util.Set;

import javax.jcr.AccessDeniedException;
import javax.jcr.Credentials;
import javax.jcr.InvalidSerializedDataException;
import javax.jcr.Item;
import javax.jcr.ItemNotFoundException;
import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
import javax.jcr.Property;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.UnsupportedRepositoryOperationException;
import javax.jcr.ValueFactory;
import javax.jcr.Workspace;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.retention.RetentionManager;
import javax.jcr.security.AccessControlManager;

import org.apache.jackrabbit.api.JackrabbitSession;
import org.apache.jackrabbit.api.security.principal.PrincipalManager;
import org.apache.jackrabbit.api.security.user.UserManager;
import org.apache.jackrabbit.api.stats.RepositoryStatistics.Type;
import org.apache.jackrabbit.commons.xml.DocumentViewExporter;
import org.apache.jackrabbit.commons.xml.Exporter;
import org.apache.jackrabbit.commons.xml.ParsingContentHandler;
import org.apache.jackrabbit.commons.xml.SystemViewExporter;
import org.apache.jackrabbit.commons.xml.ToXmlContentHandler;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.jcr.delegate.ItemDelegate;
import org.apache.jackrabbit.oak.jcr.delegate.NodeDelegate;
import org.apache.jackrabbit.oak.jcr.delegate.PropertyDelegate;
import org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate;
import org.apache.jackrabbit.oak.jcr.security.AccessManager;
import org.apache.jackrabbit.oak.jcr.session.operation.SessionOperation;
import org.apache.jackrabbit.oak.jcr.xml.ImportHandler;
import org.apache.jackrabbit.oak.spi.mount.MountInfoProvider;
import org.apache.jackrabbit.oak.spi.security.authentication.ImpersonationCredentials;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions;
import org.apache.jackrabbit.oak.stats.CounterStats;
import org.apache.jackrabbit.util.Text;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;

/**
 * TODO document
 */
public class SessionImpl implements JackrabbitSession {
    private static final Logger log = LoggerFactory.getLogger(SessionImpl.class);

    private SessionContext sessionContext;
    private SessionDelegate sd;
    private final CounterStats sessionCounter;

    public SessionImpl(SessionContext sessionContext) {
        this.sessionContext = sessionContext;
        this.sd = sessionContext.getSessionDelegate();
        this.sessionCounter = sessionContext.getCount(SESSION_COUNT);
        sessionCounter.inc();
        sessionContext.getMeter(Type.SESSION_LOGIN_COUNTER).mark();
    }

    static void checkIndexOnName(String jcrPath) throws RepositoryException {
        int pos = jcrPath.length() - 1;
        if (pos < 2 || jcrPath.charAt(pos) != ']') {
            return;
        }

        if ("0123456789".indexOf(jcrPath.charAt(--pos)) == -1) {
            return;
        }

        while (--pos >= 0) {
            char ch = jcrPath.charAt(pos);
            if (ch == '[') {
                throw new RepositoryException("Cannot create a new node using a name including an index");
            }
            if ("0123456789".indexOf(ch) == -1) {
                return;
            }
        }
    }

    private abstract class ReadOperation<T> extends SessionOperation<T> {
        protected ReadOperation(String name) {
            super(name);
        }

        @Override
        public void checkPreconditions() throws RepositoryException {
            checkAlive();
        }
    }

    private abstract class WriteOperation<T> extends SessionOperation<T> {
        protected WriteOperation(String name) {
            super(name, true);
        }

        @Override
        public void checkPreconditions() throws RepositoryException {
            checkAlive();
        }
    }

    private void checkAlive() throws RepositoryException {
        if (sd == null) {
            throw new RepositoryException("This session has been closed.");
        }
        sd.checkAlive();
    }

    @NotNull
    private String getOakPathOrThrow(@NotNull String absPath)
            throws RepositoryException {
        String p = sessionContext.getOakPathOrThrow(absPath);
        if (!PathUtils.isAbsolute(p)) {
            throw new RepositoryException("Not an absolute path: " + absPath);
        }
        return p;
    }

    @NotNull
    private String getOakPathOrThrowNotFound(@NotNull String absPath)
            throws PathNotFoundException {
        return sessionContext.getOakPathOrThrowNotFound(absPath);
    }

    @Nullable
    private ItemImpl<?> getItemInternal(@NotNull String oakPath)
            throws RepositoryException {
        checkAlive();
        ItemDelegate item = sd.getItem(oakPath);
        if (item instanceof NodeDelegate) {
            return NodeImpl.createNode((NodeDelegate) item, sessionContext);
        } else if (item instanceof PropertyDelegate) {
            return new PropertyImpl((PropertyDelegate) item, sessionContext);
        } else {
            return null;
        }
    }

    @Override
    @Nullable
    public Node getNodeOrNull(final String absPath) throws RepositoryException {
        checkNotNull(absPath);
        checkAlive();
        return sd.performNullable(new ReadOperation<Node>("getNodeOrNull") {
            @Override
            public Node performNullable() throws RepositoryException {
                try {
                    return NodeImpl.createNodeOrNull(sd.getNode(getOakPathOrThrow(absPath)), sessionContext);
                } catch (PathNotFoundException e) {
                    return null;
                }
            }
        });
    }

    @Override
    @Nullable
    public Property getPropertyOrNull(final String absPath) throws RepositoryException {
        checkAlive();
        if (checkNotNull(absPath).equals("/")) {
            return null;
        } else {
            final String oakPath;
            try {
                oakPath = getOakPathOrThrow(absPath);
            } catch (PathNotFoundException e) {
                return null;
            }
            return sd.performNullable(new ReadOperation<Property>("getPropertyOrNull") {
                @Override
                public Property performNullable() {
                    PropertyDelegate pd = sd.getProperty(oakPath);
                    if (pd != null) {
                        return new PropertyImpl(pd, sessionContext);
                    } else {
                        return null;
                    }
                }
            });
        }
    }

    @Override
    @Nullable
    public Item getItemOrNull(final String absPath) throws RepositoryException {
        checkNotNull(absPath);
        checkAlive();
        return sd.performNullable(new ReadOperation<Item>("getItemOrNull") {
            @Override
            public Item performNullable() throws RepositoryException {
                return getItemInternal(getOakPathOrThrow(absPath));
            }
        });
    }

    //------------------------------------------------------------< Session >---

    @Override
    @NotNull
    public Repository getRepository() {
        return sessionContext.getRepository();
    }

    @Override
    public String getUserID() {
        return sd.getAuthInfo().getUserID();
    }

    @Override
    public String[] getAttributeNames() {
        Set<String> names = newTreeSet(sessionContext.getAttributes().keySet());
        Collections.addAll(names, sd.getAuthInfo().getAttributeNames());
        return names.toArray(new String[names.size()]);
    }

    @Override
    public Object getAttribute(String name) {
        Object attribute = sd.getAuthInfo().getAttribute(name);
        if (attribute == null) {
            attribute = sessionContext.getAttributes().get(name);
        }
        return attribute;
    }

    @Override @NotNull
    public Workspace getWorkspace() {
        return sessionContext.getWorkspace();
    }

    @Override
    @NotNull
    public Session impersonate(Credentials credentials) throws RepositoryException {
        checkAlive();

        ImpersonationCredentials impCreds = new ImpersonationCredentials(
                checkNotNull(credentials), sd.getAuthInfo());
        return getRepository().login(impCreds, sd.getWorkspaceName());
    }

    @Override
    @NotNull
    public ValueFactory getValueFactory() throws RepositoryException {
        checkAlive();
        return sessionContext.getValueFactory();
    }

    @Override
    @NotNull
    public Node getRootNode() throws RepositoryException {
        checkAlive();
        return sd.perform(new ReadOperation<Node>("getRootNode") {
            @NotNull
            @Override
            public Node perform() throws RepositoryException {
                NodeDelegate nd = sd.getRootNode();
                if (nd == null) {
                    throw new AccessDeniedException("Root node is not accessible.");
                }
                return NodeImpl.createNode(nd, sessionContext);
            }
        });
    }

    @Override
    public Node getNode(String absPath) throws RepositoryException {
        Node node = getNodeOrNull(checkNotNull(absPath));
        if (node == null) {
            throw new PathNotFoundException("Node with path " + absPath + " does not exist.");
        }
        return node;
    }

    @Override
    public boolean nodeExists(String absPath) throws RepositoryException {
        return getNodeOrNull(checkNotNull(absPath)) != null;
    }

    @NotNull
    private Node getNodeById(@NotNull final String id) throws RepositoryException {
        checkAlive();
        return sd.perform(new ReadOperation<Node>("getNodeById") {
            @NotNull
            @Override
            public Node perform() throws RepositoryException {
                NodeDelegate nd = sd.getNodeByIdentifier(id);
                if (nd == null) {
                    throw new ItemNotFoundException("Node with id " + id + " does not exist.");
                }
                return NodeImpl.createNode(nd, sessionContext);
            }
        });
    }

    @Override
    @NotNull
    public Node getNodeByUUID(String uuid) throws RepositoryException {
        return getNodeById(checkNotNull(uuid));
    }

    @Override
    @NotNull
    public Node getNodeByIdentifier(String id) throws RepositoryException {
        return getNodeById(checkNotNull(id));
    }

    @Override
    public Property getProperty(String absPath) throws RepositoryException {
        Property property = getPropertyOrNull(checkNotNull(absPath));
        if (property == null) {
            throw new PathNotFoundException(absPath);
        }
        return property;
    }

    @Override
    public boolean propertyExists(String absPath) throws RepositoryException {
        return getPropertyOrNull(checkNotNull(absPath)) != null;
    }

    @Override
    public Item getItem(String absPath) throws RepositoryException {
        Item item = getItemOrNull(checkNotNull(absPath));
        if (item == null) {
            throw new PathNotFoundException(absPath);
        }
        return item;
    }

    @Override
    public boolean itemExists(String absPath) throws RepositoryException {
        return getItemOrNull(checkNotNull(absPath)) != null;
    }

    @Override
    public void move(String srcAbsPath, final String destAbsPath) throws RepositoryException {
        checkAlive();
        checkIndexOnName(checkNotNull(destAbsPath));
        final String srcOakPath = getOakPathOrThrowNotFound(checkNotNull(srcAbsPath));
        final String destOakPath = getOakPathOrThrowNotFound(destAbsPath);
        sd.performVoid(new WriteOperation<Void>("move") {
            @Override
            public void checkPreconditions() throws RepositoryException {
                super.checkPreconditions();
                sd.checkProtectedNode(getParentPath(srcOakPath));
                sd.checkProtectedNode(getParentPath(destOakPath));
            }

            @Override
            public void performVoid() throws RepositoryException {
                sd.move(srcOakPath, destOakPath, true);
            }
        });
    }

    @Override
    public void removeItem(final String absPath) throws RepositoryException {
        checkAlive();
        final String oakPath = getOakPathOrThrowNotFound(checkNotNull(absPath));
        sd.performVoid(new WriteOperation<Void>("removeItem") {
            @Override
            public void performVoid() throws RepositoryException {
                ItemDelegate item = sd.getItem(oakPath);
                if (item == null) {
                    throw new PathNotFoundException(absPath);
                } else if (item.isProtected()) {
                    throw new ConstraintViolationException(
                            item.getPath() + " is protected");
                } else if (!item.remove()) {
                    throw new RepositoryException(
                            item.getPath() + " could not be removed");
                }
            }
        });
    }

    @Override
    public void save() throws RepositoryException {
        checkAlive();
        sd.performVoid(new WriteOperation<Void>("save") {
            @Override
            public void performVoid() throws RepositoryException {
                sd.save(null);
            }

            @Override
            public boolean isSave() {
                return true;
            }
        });
    }

    @Override
    public void refresh(final boolean keepChanges) throws RepositoryException {
        checkAlive();
        sd.performVoid(new WriteOperation<Void>("refresh") {
            @Override
            public void performVoid() {
                sd.refresh(keepChanges);
            }

            @Override
            public boolean isRefresh() {
                return true;
            }
        });
    }

    @Override
    public boolean hasPendingChanges() throws RepositoryException {
        checkAlive();
        return sd.hasPendingChanges();
    }

    @Override
    public boolean isLive() {
        return sd != null && sd.isAlive();
    }

    @Override
    public void logout() {
        if (isLive()) {
            sessionCounter.dec();
            try {
                sd.performVoid(new SessionOperation<Void>("logout") {
                    @Override
                    public void performVoid() {
                        sessionContext.dispose();
                        sd.logout();
                    }

                    @Override
                    public boolean isLogout() {
                        return true;
                    }
                });
            } catch (RepositoryException e) {
                throw new RuntimeException("Unexpected exception thrown by operation 'logout'", e);
            } finally {
                sd = null;
                sessionContext = null;
            }
        }
    }

    @Override
    @NotNull
    public ContentHandler getImportContentHandler(String parentAbsPath,
            int uuidBehavior) throws RepositoryException {
        return new ImportHandler(checkNotNull(parentAbsPath), sessionContext,
                uuidBehavior, false);
    }

    @Override
    public void importXML(String parentAbsPath, InputStream in, int uuidBehavior)
            throws IOException, RepositoryException {
        try {
            ContentHandler handler = getImportContentHandler(
                    checkNotNull(parentAbsPath), uuidBehavior);
            new ParsingContentHandler(handler).parse(in);
        } catch (SAXException e) {
            Throwable exception = e.getException();
            if (exception instanceof RepositoryException) {
                throw (RepositoryException) exception;
            } else if (exception instanceof IOException) {
                throw (IOException) exception;
            } else {
                throw new InvalidSerializedDataException("XML parse error", e);
            }
        } finally {
            // JCR-2903
            if (in != null) {
                try {
                    in.close();
                } catch (IOException ignore) {
                }
            }
        }
    }

    /**
     * Exports content at the given path using the given exporter.
     *
     * @param path     of the node to be exported
     * @param exporter document or system view exporter
     * @throws SAXException        if the SAX event handler failed
     * @throws RepositoryException if another error occurs
     */
    private synchronized void export(String path, Exporter exporter)
            throws SAXException, RepositoryException {
        Item item = getItem(path);
        if (item.isNode()) {
            exporter.export((Node) item);
        } else {
            throw new PathNotFoundException("XML export is not defined for properties: " + path);
        }
    }

    @Override
    public void exportSystemView(String absPath, ContentHandler contentHandler,
            boolean skipBinary, boolean noRecurse) throws SAXException,
            RepositoryException {
        export(checkNotNull(absPath), new SystemViewExporter(this,
                checkNotNull(contentHandler), !noRecurse, !skipBinary));
    }

    @Override
    public void exportSystemView(String absPath, OutputStream out,
            boolean skipBinary, boolean noRecurse) throws IOException,
            RepositoryException {
        try {
            ContentHandler handler = new ToXmlContentHandler(checkNotNull(out));
            export(checkNotNull(absPath), new SystemViewExporter(this, handler,
                    !noRecurse, !skipBinary));
        } catch (SAXException e) {
            Exception exception = e.getException();
            if (exception instanceof RepositoryException) {
                throw (RepositoryException) exception;
            } else if (exception instanceof IOException) {
                throw (IOException) exception;
            } else {
                throw new RepositoryException(
                        "Error serializing system view XML", e);
            }
        }
    }

    @Override
    public void exportDocumentView(String absPath,
            ContentHandler contentHandler, boolean skipBinary, boolean noRecurse)
            throws SAXException, RepositoryException {
        export(checkNotNull(absPath), new DocumentViewExporter(this,
                checkNotNull(contentHandler), !noRecurse, !skipBinary));
    }

    @Override
    public void exportDocumentView(String absPath, OutputStream out,
            boolean skipBinary, boolean noRecurse) throws IOException,
            RepositoryException {
        try {
            ContentHandler handler = new ToXmlContentHandler(checkNotNull(out));
            export(checkNotNull(absPath), new DocumentViewExporter(this,
                    handler, !noRecurse, !skipBinary));
        } catch (SAXException e) {
            Exception exception = e.getException();
            if (exception instanceof RepositoryException) {
                throw (RepositoryException) exception;
            } else if (exception instanceof IOException) {
                throw (IOException) exception;
            } else {
                throw new RepositoryException(
                        "Error serializing document view XML", e);
            }
        }
    }

    @Override
    public void addLockToken(String lt) {
        try {
            getWorkspace().getLockManager().addLockToken(checkNotNull(lt));
        } catch (RepositoryException e) {
            log.warn("Unable to add lock token " + lt + " to session", e);
        }
    }

    @Override @NotNull
    public String[] getLockTokens() {
        try {
            return getWorkspace().getLockManager().getLockTokens();
        } catch (RepositoryException e) {
            log.warn("Unable to retrieve lock tokens from session", e);
            return new String[0];
        }
    }

    @Override
    public void removeLockToken(String lt) {
        try {
            getWorkspace().getLockManager().removeLockToken(checkNotNull(lt));
        } catch (RepositoryException e) {
            log.warn("Unable to remove lock token " + lt + " from session", e);
        }
    }

    @Override
    public boolean hasPermission(String absPath, final String actions) throws RepositoryException {
        checkAlive();
        final String oakPath = getOakPathOrThrow(checkNotNull(absPath));
        checkNotNull(actions);
        return sd.perform(new ReadOperation<Boolean>("hasPermission") {
            @NotNull
            @Override
            public Boolean perform() throws RepositoryException {
                return sessionContext.getAccessManager().hasPermissions(oakPath, actions);
            }
        });
    }

    @Override
    public void checkPermission(String absPath, String actions) throws RepositoryException {
        if (!hasPermission(checkNotNull(absPath), checkNotNull(actions))) {
            throw new AccessControlException("Access denied.");
        }
    }

    @Override
    public boolean hasCapability(String methodName, Object target, Object[] arguments) throws RepositoryException {
        checkNotNull(methodName);
        checkNotNull(target);
        checkAlive();

        if (target instanceof ItemImpl) {
            ItemDelegate dlg = ((ItemImpl<?>) target).dlg;
            if (dlg.isProtected()) {
                return false;
            }

            boolean isNode = ((ItemImpl<?>) target).isNode();
            Node parent = (isNode) ? (Node) target : ((ItemImpl<?>) target).getParent();
            if (!parent.isCheckedOut()) {
                return false;
            }
            boolean hasLocking = sessionContext.getRepository().getDescriptorValue(Repository.OPTION_LOCKING_SUPPORTED).getBoolean();
            if (hasLocking && parent.isLocked()) {
                return false;
            }

            AccessManager accessMgr = sessionContext.getAccessManager();
            long permission = Permissions.NO_PERMISSION;
            if (isNode) {
                Tree tree = ((NodeDelegate) dlg).getTree();
                if ("addNode".equals(methodName)) {
                    if (arguments != null && arguments.length > 0) {
                        // add-node needs to be checked on the (path of) the
                        // new node that has/will be added
                        String path = PathUtils.concat(tree.getPath(), sessionContext.getOakName(arguments[0].toString()));
                        return accessMgr.hasPermissions(path, Session.ACTION_ADD_NODE)  && !isMountedReadOnly(path);
                    }
                } else if ("setPrimaryType".equals(methodName) || "addMixin".equals(methodName) || "removeMixin".equals(methodName)) {
                    permission = Permissions.NODE_TYPE_MANAGEMENT;
                } else if ("orderBefore".equals(methodName)) {
                    if (tree.isRoot()) {
                        return false;
                    } else {
                        permission = Permissions.MODIFY_CHILD_NODE_COLLECTION;
                        tree = tree.getParent();
                    }
                } else if ("setProperty".equals(methodName)) {
                    permission = Permissions.ADD_PROPERTY;
                } else if ("remove".equals(methodName)) {
                    permission = Permissions.REMOVE_NODE;
                }
                return accessMgr.hasPermissions(tree, null, permission) && !isMountedReadOnly(tree.getPath());
            } else {
                if ("setValue".equals(methodName)) {
                    permission = Permissions.MODIFY_PROPERTY;
                } else if ("remove".equals(methodName)) {
                    permission = Permissions.REMOVE_PROPERTY;
                }
                NodeDelegate parentDelegate = dlg.getParent();
                if (parentDelegate != null) {
                    return accessMgr.hasPermissions(parentDelegate.getTree(), ((PropertyDelegate) dlg).getPropertyState(), permission) 
                            && !isMountedReadOnly(parentDelegate.getPath());
                } else {
                    return accessMgr.hasPermissions(dlg.getPath(), (permission == Permissions.MODIFY_PROPERTY) ? Session.ACTION_SET_PROPERTY : Session.ACTION_REMOVE)
                            && !isMountedReadOnly(dlg.getPath());
                }
            }
        }
        // TODO: add more best-effort checks
        return true;
    }

    private boolean isMountedReadOnly(String path) {
        MountInfoProvider mip = sessionContext.getMountInfoProvider();
        return mip != null && mip.getMountByPath(path).isReadOnly();
    }

    @Override
    @NotNull
    public AccessControlManager getAccessControlManager() throws RepositoryException {
        return sessionContext.getAccessControlManager();
    }

    /**
     * @see javax.jcr.Session#getRetentionManager()
     */
    @Override
    @NotNull
    public RetentionManager getRetentionManager() throws RepositoryException {
        throw new UnsupportedRepositoryOperationException("Retention Management is not supported.");
    }

    //---------------------------------------------------------< Namespaces >---

    @Override
    public void setNamespacePrefix(String prefix, String uri)
            throws RepositoryException {
        sessionContext.getNamespaces().setNamespacePrefix(checkNotNull(prefix),
                checkNotNull(uri));
    }

    @Override
    public String[] getNamespacePrefixes() throws RepositoryException {
        return sessionContext.getNamespaces().getNamespacePrefixes();
    }

    @Override
    public String getNamespaceURI(String prefix) throws RepositoryException {
        return sessionContext.getNamespaces().getNamespaceURI(
                checkNotNull(prefix));
    }

    @Override
    public String getNamespacePrefix(String uri) throws RepositoryException {
        return sessionContext.getNamespaces().getNamespacePrefix(
                checkNotNull(uri));
    }

    //--------------------------------------------------< JackrabbitSession >---

    @Override
    public boolean hasPermission(String absPath, String... actions) throws RepositoryException {
        return hasPermission(absPath, Text.implode(actions, ","));
    }

    @Override
    @NotNull
    public PrincipalManager getPrincipalManager() throws RepositoryException {
        return sessionContext.getPrincipalManager();
    }

    @Override
    @NotNull
    public UserManager getUserManager() throws RepositoryException {
        return sessionContext.getUserManager();
    }

    @Override
    public String toString() {
        if (isLive()) {
            return sd.getContentSession().toString();
        }
        return "null";
    }
}
