/*
 * 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.impl.vlt.serialization;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;

import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.jackrabbit.vault.fs.Mounter;
import org.apache.jackrabbit.vault.fs.api.RepositoryAddress;
import org.apache.jackrabbit.vault.fs.api.SerializationType;
import org.apache.jackrabbit.vault.fs.api.VaultFile;
import org.apache.jackrabbit.vault.fs.api.VaultFileSystem;
import org.apache.jackrabbit.vault.fs.impl.io.XmlAnalyzer;
import org.apache.jackrabbit.vault.util.Constants;
import org.apache.jackrabbit.vault.util.PlatformNameFormat;
import org.apache.jackrabbit.vault.util.RepositoryProvider;
import org.apache.jackrabbit.vault.util.Text;
import org.apache.sling.ide.impl.vlt.VaultFsLocator;
import org.apache.sling.ide.log.Logger;
import org.apache.sling.ide.serialization.SerializationDataBuilder;
import org.apache.sling.ide.serialization.SerializationException;
import org.apache.sling.ide.serialization.SerializationKind;
import org.apache.sling.ide.serialization.SerializationManager;
import org.apache.sling.ide.transport.ResourceProxy;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

@Component(service = SerializationManager.class)
public class VltSerializationManager implements SerializationManager {

    static final String EXTENSION_XML = ".xml";

    @Reference
    private VltSerializationDataBuilder builder;
    
    @Reference
    private Logger logger;

    public static void main(String[] args) throws RepositoryException, URISyntaxException, IOException {
        RepositoryAddress address = new RepositoryAddress("http://localhost:8080/server/root");
        Repository repo = new RepositoryProvider().getRepository(address);
        Session session = repo.login(new SimpleCredentials("admin", "admin".toCharArray()));

        VaultFileSystem fs = Mounter.mount(null, null, address, "/", session);

        String[] attempts = new String[] { "/rep:policy", "/var" };

        for (String attempt : attempts) {
            VaultFile vaultFile = fs.getFile(attempt);

            System.out.println(attempt + " -> " + vaultFile);
        }

        for (String attempt : attempts) {

            attempt = PlatformNameFormat.getPlatformPath(attempt) + EXTENSION_XML;

            VaultFile vaultFile = fs.getFile(attempt);

            System.out.println(attempt + " -> " + vaultFile);
        }

    }

    @Override
    public void destroy() {

    }

    @Override
    public boolean isSerializationFile(String filePath) {
        
        File file = new File(filePath);
        String fileName = file.getName();
        if (fileName.equals(Constants.DOT_CONTENT_XML)) {
            return true;
        }

        if (!fileName.endsWith(EXTENSION_XML)) {
            return false;
        }

        // TODO - refrain from doing I/O here
        // TODO - copied from TransactionImpl
        
        try (InputStream in = new BufferedInputStream(new FileInputStream(file))) {
            SerializationType serType = XmlAnalyzer.analyze(new InputSource(in));
            return serType == SerializationType.XML_DOCVIEW;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public String getBaseResourcePath(String serializationFilePath) {

        File file = new File(serializationFilePath);
        String fileName = file.getName();
        if (fileName.equals(Constants.DOT_CONTENT_XML)) {
            return file.getParent();
        }

        if (!fileName.endsWith(EXTENSION_XML)) {
            return file.getAbsolutePath();
        }

        // assume that delete file with the xml extension is a full serialization aggregate
        // TODO - this can generate false results
        if (!file.exists()) {
            return getPathWithoutXmlExtension(file);
        }

        // TODO - refrain from doing I/O here
        // TODO - copied from TransactionImpl
        
        try (InputStream in = new BufferedInputStream(new FileInputStream(file))) {
            SerializationType serType = XmlAnalyzer.analyze(new InputSource(in));
            if (serType == SerializationType.XML_DOCVIEW) {
                return getPathWithoutXmlExtension(file);
            }

            return file.getAbsolutePath();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private String getPathWithoutXmlExtension(File file) {
        return file.getAbsolutePath().substring(0, file.getAbsolutePath().length() - EXTENSION_XML.length());
    }

    @Override
    public String getSerializationFilePath(String baseFilePath, SerializationKind serializationKind) {

        switch (serializationKind) {
            case FOLDER:
            case METADATA_PARTIAL:
                return baseFilePath + File.separatorChar + Constants.DOT_CONTENT_XML;
            case METADATA_FULL:
                return baseFilePath;
            case FILE:
                return baseFilePath + ".dir" + File.separatorChar + Constants.DOT_CONTENT_XML;
        }

        throw new IllegalArgumentException("Unsupported serialization kind " + serializationKind);
    }

    @Override
    public String getRepositoryPath(String osPath) {

        String repositoryPath;
        String name = Text.getName(osPath);
        if (name.equals(Constants.DOT_CONTENT_XML)) {
            // TODO - this is a bit risky, we might clean legitimate directories which contain '.dir'
            String parentPath = Text.getRelativeParent(osPath, 1);
            if (parentPath != null && parentPath.endsWith(".dir")) {
                parentPath = parentPath.substring(0, parentPath.length() - ".dir".length());
            }
            repositoryPath = PlatformNameFormat.getRepositoryPath(parentPath);
        } else {
            // TODO - we assume here that it's a full coverage aggregate but it might not be
            if (osPath.endsWith(EXTENSION_XML)) {
                repositoryPath = PlatformNameFormat.getRepositoryPath(osPath.substring(0, osPath.length()
                        - EXTENSION_XML.length()));
            } else {
                repositoryPath = PlatformNameFormat.getRepositoryPath(osPath).replace(".dir/", "/");
            }
        }

        // TODO extract into PathUtils
        if (repositoryPath.length() > 0 && repositoryPath.charAt(0) != '/') {
            repositoryPath = '/' + repositoryPath;
        } else if (repositoryPath.length() == 0) {
            repositoryPath = "/";
        }

        return repositoryPath;
    }

    @Override
    public String getOsPath(String repositoryPath) {
        return PlatformNameFormat.getPlatformPath(repositoryPath);
    }

    protected void bindVaultFsLocator(VaultFsLocator fsLocator) {

        getBuilder().setLocator(fsLocator);
    }

    protected void unbindVaultFsLocator(VaultFsLocator fsLocator) {

        getBuilder().setLocator(null);
    }
    
    private VltSerializationDataBuilder getBuilder() {
    	if (builder==null) {
    		builder = new VltSerializationDataBuilder(logger);
    	}
    	return builder;
    }
    
    @Override
    public SerializationDataBuilder newBuilder(
    		org.apache.sling.ide.transport.Repository repository,
    		File contentSyncRoot) throws SerializationException {
    	VltSerializationDataBuilder b = getBuilder();
    	b.init(repository, contentSyncRoot);
    	return b;
    }

    @Override
    public ResourceProxy readSerializationData(String filePath, InputStream source) throws IOException {

        if (source == null)
            return null;

        String repositoryPath = getRepositoryPath(filePath);

        try {
            SAXParserFactory factory = SAXParserFactory.newInstance();
            factory.setNamespaceAware(true);
            factory.setFeature("http://xml.org/sax/features/namespace-prefixes", false);
            SAXParser parser = factory.newSAXParser();
            ContentXmlHandler handler = new ContentXmlHandler(repositoryPath, logger);
            parser.parse(source, handler);

            return handler.getRoot();
        } catch (SAXException | ParserConfigurationException e) {
            // TODO proper error handling
            throw new IOException(e);
        }
    }
}
