/*
 * Copyright 2017-present Open Networking Foundation
 *
 * Licensed 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.onosproject.yang.impl;

import com.google.common.io.ByteStreams;
import com.google.common.io.Files;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Service;
import org.onlab.util.FilePathValidator;
import org.onosproject.yang.YangLiveCompilerService;
import org.onosproject.yang.compiler.tool.DefaultYangCompilationParam;
import org.onosproject.yang.compiler.tool.YangCompilerManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileVisitResult;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import static com.google.common.io.ByteStreams.toByteArray;
import static com.google.common.io.Files.createParentDirs;
import static com.google.common.io.Files.write;
import static java.nio.file.Files.walkFileTree;

/**
 * Represents implementation of YANG live compiler manager.
 */
@Service
@Component(immediate = true)
public class YangLiveCompilerManager implements YangLiveCompilerService {

    private final Logger log = LoggerFactory.getLogger(getClass());

    private static final String ZIP_MAGIC = "PK";

    @Activate
    public void activate() {
        log.info("Started");
    }

    @Deactivate
    public void deactivate() {
        log.info("Stopped");
    }

    @Override
    public InputStream compileYangFiles(String modelId,
                                        InputStream yangSources) throws IOException {
        // Generate temporary directory where the work will happen.
        File root = Files.createTempDir();
        log.info("Compiling YANG model to {}", root);

        // Unpack the input stream
        File yangRoot = unpackYangSources(root, yangSources);

        // Run the YANG compilation phase
        File javaRoot = runYangCompiler(root, yangRoot, modelId);

        // Run the Java compilation phase
        File classRoot = runJavaCompiler(root, javaRoot, modelId);

        // Run the JAR assembly phase
        File jarFile = runJarAssembly(root, classRoot, modelId);

        // Return the final JAR file as input stream
        return new FileInputStream(jarFile);
    }

    // Unpacks the given input stream into the YANG root subdirectory of the specified root directory.
    private File unpackYangSources(File root, InputStream yangSources) throws IOException {
        File yangRoot = new File(root, "yang/");
        if (yangRoot.mkdirs()) {
            // Unpack the yang sources into the newly created directory
            byte[] cache = toByteArray(yangSources);
            InputStream bis = new ByteArrayInputStream(cache);
            if (isZipArchive(cache)) {
                extractZipArchive(yangRoot, bis);
            } else {
                extractYangFile(yangRoot, bis);
            }
            return yangRoot;
        }
        throw new IOException("Unable to create yang source root");
    }

    // Extracts the YANG source stream into the specified directory.
    private void extractYangFile(File dir, InputStream stream) throws IOException {
        ByteStreams.copy(stream, new FileOutputStream(new File(dir, "model.yang")));
    }

    // Extracts the ZIP stream into the specified directory.
    private void extractZipArchive(File dir, InputStream stream) throws IOException {
        ZipInputStream zis = new ZipInputStream(stream);
        ZipEntry entry;
        while ((entry = zis.getNextEntry()) != null) {
            if (FilePathValidator.validateZipEntry(entry, dir)) {
                if (!entry.isDirectory()) {
                    byte[] data = toByteArray(zis);
                    zis.closeEntry();
                    File file = new File(dir, entry.getName());
                    createParentDirs(file);
                    write(data, file);
                }
            } else {
                throw new IOException("Zip archive is attempting to create a file outside of its root");
            }
        }
        zis.close();
    }

    // Runs the YANG compiler on the YANG sources in the specified directory.
    private File runYangCompiler(File root, File yangRoot, String modelId) throws IOException {
        File javaRoot = new File(root, "java/");
        if (javaRoot.mkdirs()) {
            // Prepare the compilation parameter
            DefaultYangCompilationParam.Builder param = DefaultYangCompilationParam.builder()
                    .setCodeGenDir(new File(javaRoot, "src").toPath())
                    .setMetadataGenDir(new File(javaRoot, "schema").toPath())
                    .setModelId(modelId);

            // TODO: How to convey YANG dependencies? "/dependencies" directory?

            // Iterate over all files and add all YANG sources.
            walkFileTree(Paths.get(yangRoot.getAbsolutePath()),
                         new SimpleFileVisitor<Path>() {
                             @Override
                             public FileVisitResult visitFile(Path file, BasicFileAttributes attributes)
                                     throws IOException {
                                 if (attributes.isRegularFile() && file.toString().endsWith(".yang")) {
                                     param.addYangFile(file);
                                 }
                                 return FileVisitResult.CONTINUE;
                             }
                         });

            // Run the YANG compiler and collect the results
            new YangCompilerManager().compileYangFiles(param.build());
            return javaRoot;
        }
        throw new IOException("Unable to create Java results root");
    }

    // Runs the Java compilation on the Java sources generated by YANG compiler.
    private File runJavaCompiler(File root, File javaRoot, String modelId) throws IOException {
        File classRoot = new File(root, "classes/");
        if (classRoot.mkdirs()) {
            File compilerScript = writeResource("onos-yang-javac", root);
            writeResource("YangModelRegistrator.java", root);
            execute(new String[]{
                    "bash",
                    compilerScript.getAbsolutePath(),
                    javaRoot.getAbsolutePath(),
                    classRoot.getAbsolutePath(),
                    modelId
            });
            return classRoot;
        }
        throw new IOException("Unable to create class results root");
    }

    // Run the JAR assembly on the classes root and include any YANG sources as well.
    private File runJarAssembly(File root, File classRoot, String modelId) throws IOException {
        File jarFile = new File(root, "model.jar");
        File jarScript = writeResource("onos-yang-jar", root);
        writeResource("app.xml", root);
        writeResource("features.xml", root);
        writeResource("YangModelRegistrator.xml", root);
        execute(new String[]{
                "bash",
                jarScript.getAbsolutePath(),
                classRoot.getAbsolutePath(),
                jarFile.getAbsolutePath(),
                modelId
        });
        return jarFile;
    }

    // Writes the specified resource as a file in the given directory.
    private File writeResource(String resourceName, File dir) throws IOException {
        File script = new File(dir, resourceName);
        write(toByteArray(getClass().getResourceAsStream("/" + resourceName)), script);
        return script;
    }

    // Indicates whether the stream encoded in the given bytes is a ZIP archive.
    private boolean isZipArchive(byte[] bytes) {
        return substring(bytes, ZIP_MAGIC.length()).equals(ZIP_MAGIC);
    }

    // Returns the substring of maximum possible length from the specified bytes.
    private String substring(byte[] bytes, int length) {
        return new String(bytes, 0, Math.min(bytes.length, length), StandardCharsets.UTF_8);
    }

    // Executes the given command arguments as a system command.
    private void execute(String[] command) throws IOException {
        try {
            Process process = Runtime.getRuntime().exec(command);
            byte[] output = toByteArray(process.getInputStream());
            byte[] error = toByteArray(process.getErrorStream());
            int code = process.waitFor();
            if (code != 0) {
                log.info("Command failed: status={}, output={}, error={}",
                         code, new String(output), new String(error));
            }
        } catch (InterruptedException e) {
            log.error("Interrupted executing command {}", command, e);
            Thread.currentThread().interrupt();
        }
    }
}
