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

import org.apache.commons.io.IOUtils;
import org.glassfish.jersey.media.multipart.FormDataBodyPart;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataMultiPart;
import org.onosproject.rest.AbstractWebResource;
import org.onosproject.yang.compiler.api.YangCompilationParam;
import org.onosproject.yang.compiler.api.YangCompilerService;
import org.onosproject.yang.compiler.datamodel.YangNode;
import org.onosproject.yang.compiler.tool.DefaultYangCompilationParam;
import org.onosproject.yang.compiler.tool.YangCompilerManager;
import org.onosproject.yang.model.YangModel;
import org.onosproject.yang.runtime.DefaultModelRegistrationParam;
import org.onosproject.yang.runtime.ModelRegistrationParam;
import org.onosproject.yang.runtime.YangModelRegistry;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Paths;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import static org.onosproject.yang.compiler.tool.YangCompilerManager.deSerializeDataModel;
import static org.onosproject.yang.compiler.tool.YangCompilerManager.processYangModel;
import static org.onosproject.yang.compiler.utils.io.impl.YangIoUtils.deleteDirectory;

/**
 * Yang files upload resource.
 */
@Path("models")
public class YangWebResource extends AbstractWebResource {
    private static final String YANG_FILE_EXTENSION = ".yang";
    private static final String SER_FILE_EXTENSION = ".ser";
    private static final String JAR_FILE_EXTENSION = ".jar";
    private static final String ZIP_FILE_EXTENSION = ".zip";
    private static final String REGISTER = "register";
    private static final String UNREGISTER = "unregister";
    private static final String CODE_GEN_DIR = "target/generated-sources/";
    private static final String YANG_RESOURCES = "target/yang/resources/";
    private static final String SERIALIZED_FILE_NAME = "YangMetaData.ser";
    private static final String UNKNOWN_KEY = "Key must be either register " +
            "or unregister.";
    private static final String SLASH = "/";

    /**
     * Compiles and registers the given yang files.
     *
     * @param formData YANG files or ser files
     * @return 200 OK
     * @throws IOException when fails to generate a file
     */
    @POST
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    public Response upload(FormDataMultiPart formData) throws IOException {
        Map<String, List<File>> input = parseInputData(formData);

        for (Map.Entry<String, List<File>> entry : input.entrySet()) {
            deleteDirectory(CODE_GEN_DIR);
            deleteDirectory(YANG_RESOURCES);

            YangCompilerService liveCompiler = get(YangCompilerService.class);
            liveCompiler.compileYangFiles(createCompilationParam(
                    entry.getValue()));

            YangModelRegistry modelRegistry = get(YangModelRegistry.class);
            String key = entry.getKey();
            if (key.equalsIgnoreCase(REGISTER)) {
                modelRegistry.registerModel(getModelRegParam());
            } else if (key.equalsIgnoreCase(UNREGISTER)) {
                modelRegistry.unregisterModel(getModelRegParam());
            } else {
                return Response.serverError().entity(UNKNOWN_KEY).build();
            }
        }

        // TODO : create bundles

        return Response.status(200).build();
    }

    private File getInputFile(InputStream stream, String fileName)
            throws IOException {
        byte[] content = IOUtils.toByteArray(stream);
        File file = new File(fileName);
        if (!file.exists()) {
            file.createNewFile();
        }
        FileOutputStream fop = new FileOutputStream(file);
        fop.write(content);
        fop.flush();
        fop.close();
        return file;
    }

    private Map<String, List<File>> parseInputData(FormDataMultiPart formData)
            throws IOException {
        Map<String, List<File>> input = new HashMap<>();
        Map<String, List<FormDataBodyPart>> fieldsByName = formData.getFields();
        for (Map.Entry<String, List<FormDataBodyPart>> entry :
                fieldsByName.entrySet()) {
            List<File> inputFiles = new LinkedList<>();
            for (FormDataBodyPart field : entry.getValue()) {
                InputStream stream = field.getEntityAs(InputStream.class);
                FormDataContentDisposition content = field
                        .getFormDataContentDisposition();
                String fileName = content.getFileName();
                inputFiles.add(getInputFile(stream, fileName));
            }
            input.put(entry.getKey(), inputFiles);
        }
        return input;
    }

    private YangCompilationParam createCompilationParam(List<File> inputFiles)
            throws IOException {
        DefaultYangCompilationParam.Builder builder = DefaultYangCompilationParam.builder();
        for (File file : inputFiles) {
            if (file.getName().endsWith(JAR_FILE_EXTENSION)
                    || file.getName().endsWith(ZIP_FILE_EXTENSION)) {
                List<File> files = decompressFile(file);

                for (File f : files) {
                    addToParam(builder, f);
                }
            } else {
                addToParam(builder, file);
            }
        }
        builder.setCodeGenDir(Paths.get(CODE_GEN_DIR));
        builder.setMetadataGenDir(Paths.get(YANG_RESOURCES));
        return builder.build();
    }

    private void addToParam(DefaultYangCompilationParam.Builder builder,
                                            File file) {
        if (file.getName().endsWith(YANG_FILE_EXTENSION)) {
            builder.addYangFile(Paths.get(file.getAbsolutePath()));
        } else if (file.getName().endsWith(SER_FILE_EXTENSION)) {
            builder.addDependentSchema(Paths.get(file.getAbsolutePath()));
        }
    }

    private ModelRegistrationParam getModelRegParam() throws IOException {
        String metaPath = YANG_RESOURCES + SERIALIZED_FILE_NAME;
        List<YangNode> curNodes = getYangNodes(metaPath);
        // FIXME: extract or derive the model id from the web request
        String modelId = "unknown";
        if (curNodes != null && !curNodes.isEmpty()) {
            YangModel model = processYangModel(metaPath, curNodes, modelId, false);
            return DefaultModelRegistrationParam.builder()
                    .setYangModel(model).build();
        }
        return null;
    }

    private List<YangNode> getYangNodes(String path) throws IOException {
        List<YangNode> nodes = new LinkedList<>();
        File file = new File(path);
        if (file.getName().endsWith(SER_FILE_EXTENSION)) {
            nodes.addAll(YangCompilerManager.getYangNodes(deSerializeDataModel(file.toString())));
        }
        return nodes;
    }

    private static List<File> decompressFile(File jarFile)
            throws IOException {
        ZipFile zip = new ZipFile(jarFile);
        final List<File> unzipedFiles = new LinkedList<>();

        // first get all directories,
        // then make those directory on the destination Path
        for (Enumeration<? extends ZipEntry> enums = zip.entries();
             enums.hasMoreElements();) {
            ZipEntry entry = enums.nextElement();

            String fileName = YANG_RESOURCES + entry.getName();
            File f = new File(fileName);

            if (fileName.endsWith(SLASH)) {
                f.mkdirs();
            }
        }

        //now create all files
        for (Enumeration<? extends ZipEntry> enums = zip.entries();
             enums.hasMoreElements();) {
            ZipEntry entry = enums.nextElement();
            String fileName = YANG_RESOURCES + entry.getName();
            File f = new File(fileName);

            if (!fileName.endsWith(SLASH)) {
                InputStream is = zip.getInputStream(entry);
                FileOutputStream fos = new FileOutputStream(f);

                // write contents of 'is' to 'fos'
                while (is.available() > 0) {
                    fos.write(is.read());
                }
                unzipedFiles.add(f);
                fos.close();
                is.close();
            }
        }
        return unzipedFiles;
    }
}
