/*
 * 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.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) {
                // TODO-m12n - reactivate this error trace
//                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() {

    }
}
