package org.apache.sling.installer.factory.model.impl;/*
 * 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.
 */

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.apache.sling.installer.api.InstallableResource;
import org.apache.sling.installer.api.tasks.RegisteredResource;
import org.apache.sling.installer.api.tasks.ResourceTransformer;
import org.apache.sling.installer.api.tasks.TransformationResult;
import org.apache.sling.provisioning.model.Artifact;
import org.apache.sling.provisioning.model.Feature;
import org.apache.sling.provisioning.model.Model;
import org.apache.sling.provisioning.model.ModelUtility;
import org.apache.sling.provisioning.model.Traceable;
import org.apache.sling.provisioning.model.io.ModelArchiveReader;
import org.apache.sling.provisioning.model.io.ModelReader;
import org.apache.sling.provisioning.model.io.ModelWriter;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Version;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * This transformer detects a file with the ending ".model" containing
 * a provisioning model or a model archive ending in ".mar"
 */
@Component(service = ResourceTransformer.class)
public class ModelTransformer implements ResourceTransformer {

    public static final String TYPE_PROV_MODEL = "provisioningmodel";

    public static final String ATTR_MODEL = "model";

    public static final String ATTR_FEATURE_INDEX = "feature";

    public static final String ATTR_BASE_PATH = "path";

    public static final String ATTR_FEATURE_NAME = "name";

    /** Logger. */
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    private BundleContext bundleContext;

    @Activate
    private void activate(final BundleContext bc) {
        this.bundleContext = bc;
    }

    @Override
    public TransformationResult[] transform(final RegisteredResource resource) {
        Model model = null;
        File baseDir = null;
        if ( resource.getType().equals(InstallableResource.TYPE_FILE) && resource.getURL().endsWith(".model") ) {
            try ( final Reader reader = new InputStreamReader(resource.getInputStream(), "UTF-8") ) {
                model = ModelReader.read(reader, resource.getURL());
            } catch ( final IOException ioe) {
                logger.info("Unable to read model from " + resource.getURL(), ioe);
            }
        }
        if ( resource.getType().equals(InstallableResource.TYPE_FILE) && resource.getURL().endsWith(".mar") ) {
            baseDir = this.bundleContext.getDataFile("");
            try ( final InputStream is = resource.getInputStream() ) {

                model = ModelArchiveReader.read(is, new ModelArchiveReader.ArtifactConsumer() {
                    @Override
                    public void consume(final Artifact artifact, final InputStream is) throws IOException {
                        // nothing to do, install task does extraction
                    }
                });
            } catch ( final IOException ioe) {
                logger.info("Unable to read model from " + resource.getURL(), ioe);
            }
        }
        if ( model != null ) {
            Map<Traceable, String> errors = ModelUtility.validate(model);
            if ( errors == null ) {
                try {
                    final Model effectiveModel = ModelUtility.getEffectiveModel(model);

                    errors = ModelUtility.validateIncludingVersion(effectiveModel);
                    if ( errors == null ) {

                        String modelTxt = null;
                        try ( final StringWriter sw = new StringWriter()) {
                            ModelWriter.write(sw, effectiveModel);
                            modelTxt = sw.toString();
                        } catch ( final IOException ioe) {
                            logger.info("Unable to read model from " + resource.getURL(), ioe);
                        }

                        if ( modelTxt != null ) {
                            final TransformationResult[] result = new TransformationResult[effectiveModel.getFeatures().size()];
                            int index = 0;
                            for(final Feature f : effectiveModel.getFeatures()) {

                                final TransformationResult tr = new TransformationResult();
                                tr.setResourceType(TYPE_PROV_MODEL);
                                tr.setId(f.getName());
                                tr.setVersion(new Version(f.getVersion()));

                                final Map<String, Object> attributes = new HashMap<>();
                                attributes.put(ATTR_MODEL, modelTxt);
                                attributes.put(ATTR_FEATURE_INDEX, index);
                                attributes.put(ATTR_FEATURE_NAME, f.getName() + "-" + f.getVersion());
                                if ( baseDir != null ) {
                                    final File dir = new File(baseDir, f.getName() + "-" + f.getVersion());
                                    attributes.put(ATTR_BASE_PATH, dir.getAbsolutePath());
                                }
                                tr.setAttributes(attributes);

                                result[index] = tr;
                                index++;
                            }
                            return result;
                        }
                    }
                } catch ( final IllegalArgumentException iae ) {
                    errors = Collections.singletonMap((Traceable)model, iae.getMessage());
                }
            }
            if ( errors != null ) {
                logger.warn("Errors during parsing model at {} : {}", resource.getURL(), errors.values());
            }
        }
        return null;
    }
}
