/*
 * 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.sling.ide.test.impl.helpers;

import static org.junit.Assert.assertThat;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.jcr.Credentials;
import javax.jcr.Node;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.io.IOUtils;
import org.apache.jackrabbit.util.Text;
import org.apache.sling.ide.jcr.RepositoryUtils;
import org.apache.sling.ide.transport.RepositoryInfo;
import org.hamcrest.CoreMatchers;

/**
 * The <tt>RepositoryAccessor</tt> makes it simple to access and validate the contents of a Sling repository during
 * testing
 *
 */
public class RepositoryAccessor {

    private final LaunchpadConfig config;
    private final HttpClient client;
    private Repository repository;
    private Credentials credentials;

    public RepositoryAccessor(LaunchpadConfig config) {
        this.config = config;

        client = new HttpClient();
        client.getParams().setAuthenticationPreemptive(true);
        client.getState().setCredentials(new AuthScope(config.getHostname(), config.getPort()),
                new UsernamePasswordCredentials(config.getUsername(), config.getPassword()));
    }

    public void assertGetIsSuccessful(String path, String expectedResult) throws HttpException, IOException {

        GetMethod m = new GetMethod(config.getUrl() + path);
        InputStream input = null;
        try {
            int result = client.executeMethod(m);

            assertThat("Unexpected status call for " + m.getURI(), result, CoreMatchers.equalTo(200));

            input = m.getResponseBodyAsStream();
            String responseBody = IOUtils.toString(input, m.getRequestCharSet());

            assertThat("Unexpected response for " + m.getURI(), responseBody,
                    CoreMatchers.equalTo(expectedResult));
        } finally {
            IOUtils.closeQuietly(input);
            m.releaseConnection();
        }
    }

    public void assertGetReturns404(String path) throws HttpException, IOException {

        GetMethod m = new GetMethod(config.getUrl() + path);
        try {
            int result = client.executeMethod(m);

            assertThat("Unexpected status call for " + m.getURI(), result, CoreMatchers.equalTo(404));
        } finally {
            m.releaseConnection();
        }
    }

    public void tryDeleteResource(String path) throws RepositoryException {

        // PostMethod pm = new PostMethod(config.getUrl() + "hello.txt");
        // Part[] parts = { new StringPart(":operation", "delete") };
        // pm.setRequestEntity(new MultipartRequestEntity(parts, pm.getParams()));
        // try {
        // client.executeMethod(pm);
        // } finally {
        // pm.releaseConnection();
        // }

        Session session = login();
        if (session.nodeExists(path)) {
            session.removeItem(path);
            session.save();
        }
    }

    public Node getNode(String nodePath) throws RepositoryException {

        return login().getNode(nodePath);
    }

    /**
     * Returns true if a node exists at the specified path
     * 
     * @param path the path, in absolute format or relative to the repository root
     * @return true if the path exists, false otherwise
     * @throws RepositoryException
     */
    public boolean hasNode(String path) throws RepositoryException {
        if (path.startsWith("/")) {
            path = path.substring(1);
        }

        return login().getRootNode().hasNode(path);
    }

    public void createNode(String path, String primaryNodeType) throws RepositoryException {

        Session session = login();
        try {
            if (session.nodeExists(path)) {
                return;
            }

            Node parent = session.getNode(Text.getRelativeParent(path, 1));
            parent.addNode(Text.getName(path), primaryNodeType);
            session.save();
        } finally {
            session.logout();
        }
    }

    public void createFile(String path, byte[] bytes) throws RepositoryException {
        Session session = login();
        try {
            if (session.nodeExists(path)) {
                return;
            }

            Node parent = session.getNode(Text.getRelativeParent(path, 1));
            Node resourceNode = parent.addNode(Text.getName(path), "nt:file");
            Node contentNode = resourceNode.addNode("jcr:content", "nt:resource");
            contentNode
                    .setProperty("jcr:data", session.getValueFactory().createBinary(new ByteArrayInputStream(bytes)));
            session.save();
        } finally {
            session.logout();
        }
    }
    
    /**
     * Executes a user-specified <tt>runnable</tt> on the repository
     * 
     * <p>
     * All exceptions are propagated as they happen. It is the responsibility of the runnable to call
     * <tt>session.save()</tt> to persist the changes.
     * </p>
     * 
     * @param runnable
     * @return the result of the runnable's execution
     * @throws RepositoryException any exception that occurs when executing the runnable
     */
    public <T> T doWithSession(SessionRunnable<T> runnable) throws RepositoryException {

        Session session = login();
        try {
            return runnable.doWithSession(session);
        } finally {
            session.logout();
        }
    }

    private Session login() throws RepositoryException {
        
        RepositoryInfo repositoryInfo = new RepositoryInfo(config.getUsername(), config.getPassword(), config.getUrl());

        if (repository == null) {
            repository = RepositoryUtils.getRepository(repositoryInfo);
        }

        if (credentials == null) {
            credentials = RepositoryUtils.getCredentials(repositoryInfo);
        }
        
        return repository.login(credentials);
    }


    public interface SessionRunnable<T> {
        public T doWithSession(Session session) throws RepositoryException;
    }
}
