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

import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

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

import org.apache.jackrabbit.vault.davex.DAVExRepositoryFactory;
import org.apache.jackrabbit.vault.fs.api.RepositoryAddress;
import org.apache.jackrabbit.vault.fs.api.RepositoryFactory;
import org.apache.sling.ide.impl.vlt.Activator;
import org.apache.sling.ide.transport.RepositoryInfo;

public abstract class RepositoryUtils {

    private static final Object SYNC = new Object();
    /** 
     *  Path of DavEx server (by default listens on {@code /server}, for AEM below {@code /crx/server}), followed by workspace name.
     *  Must not start with a slash.
     *  Always give explicit workspace name to workaround the faulty fix from  https://issues.apache.org/jira/browse/JCRVLT-144.
     *  The original issue is https://issues.apache.org/jira/browse/JCR-4120, as soon as that one is fixed, 
     *  the default workspace name does no longer need to be explicitly listed here.
     *  @see RepositoryAddress
     */
    static final String[] WEBDAV_URL_LOCATIONS = new String[] { "server/default/jcr:root", "crx/server/crx.default/jcr:root" };
    private static final RepositoryFactory FACTORY = new DAVExRepositoryFactory();
    private static final Map<RepositoryAddress, Repository> REGISTERED_REPOSITORIES = new HashMap<>();
    
    public static Repository getRepository(RepositoryInfo repositoryInfo) throws RepositoryException {
        final RepositoryAddress repositoryAddress = getRepositoryAddress(repositoryInfo);
        synchronized (SYNC) {
            // will be populated implicitly by call to getRepositoryAddress
            return REGISTERED_REPOSITORIES.get(repositoryAddress);
        }
    }

    public static RepositoryAddress getRepositoryAddress(RepositoryInfo repositoryInfo) {
        StringBuilder errors = new StringBuilder();
        for (String webDavUrlLocation : WEBDAV_URL_LOCATIONS) {

            Session session = null;
            String url = repositoryInfo.appendPath(webDavUrlLocation);
            try {
                RepositoryAddress address = new RepositoryAddress(url);
                Repository repository;
                synchronized (SYNC) {
                    repository = REGISTERED_REPOSITORIES.get(address);

                    if (repository == null) {
                        Set<String> supportedSchemes = FACTORY.getSupportedSchemes();
                        if (!supportedSchemes.contains(address.getURI().getScheme())) {
                            throw new IllegalArgumentException("Unable to create a a repository for "
                                    + address.getURI()
                                    + ", since the scheme is unsupported. Only schemes '" + supportedSchemes
                                    + "' are supported");
                        }

                        // SLING-3739: ensure that a well-known ClassLoader is used
                        ClassLoader old = Thread.currentThread().getContextClassLoader();
                        Thread.currentThread().setContextClassLoader(Repository.class.getClassLoader());
                        try {
                            repository = FACTORY.createRepository(address);
                        } finally {
                            Thread.currentThread().setContextClassLoader(old);
                        }
                        REGISTERED_REPOSITORIES.put(address, repository);
                    }
                }

                session = repository.login(new SimpleCredentials(repositoryInfo.getUsername(), repositoryInfo
                        .getPassword().toCharArray()));
                return address;
            } catch (URISyntaxException e) {
                throw new RuntimeException(e);
            } catch (RepositoryException e) {
                Activator.getDefault().getPluginLogger().trace("Failed connecting to repository at " + url, e);
                errors.append(url).append(" : ").append(e.getMessage()).append('\n');
                continue;
            } finally {
                if (session != null) {
                    session.logout();
                }
            }
        }

        errors.deleteCharAt(errors.length() - 1);

        throw new IllegalArgumentException("No repository found at " + repositoryInfo.getUrl() + "\n"
                + errors.toString());

    }

    public static Credentials getCredentials(RepositoryInfo repositoryInfo) {

        return new SimpleCredentials(repositoryInfo.getUsername(), repositoryInfo.getPassword().toCharArray());
    }

    private RepositoryUtils() {

    }
}
