/*
 * 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.scripting.console.internal;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.io.IOUtils;
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.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.felix.utils.json.JSONWriter;
import org.apache.felix.webconsole.AbstractWebConsolePlugin;
import org.apache.felix.webconsole.DefaultVariableResolver;
import org.apache.felix.webconsole.SimpleWebConsolePlugin;
import org.apache.felix.webconsole.WebConsoleUtil;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.scripting.SlingBindings;
import org.apache.sling.api.scripting.SlingScript;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component
@Service
@Property(name = "felix.webconsole.label", value = ScriptConsolePlugin.NAME)
public class ScriptConsolePlugin extends SimpleWebConsolePlugin {

    private Logger log = LoggerFactory.getLogger(getClass());
    public static final String NAME = "scriptconsole";
    private static final String TITLE = "%script.title";
    private static final String[] CSS = {"/res/ui/codemirror/lib/codemirror.css","/res/ui/script-console.css"};
    private final String TEMPLATE;
    private BundleContext bundleContext;

    @Reference
    private ScriptEngineManager scriptEngineManager;

    public ScriptConsolePlugin() {
        super(NAME, TITLE, processFileNames(CSS));
        TEMPLATE = readTemplateFile("/templates/script-console.html");
    }

    @SuppressWarnings("unchecked")
    @Override
    protected void renderContent(HttpServletRequest request,
                                 HttpServletResponse response) throws ServletException, IOException {
        final PrintWriter pw = response.getWriter();
        DefaultVariableResolver varResolver = (DefaultVariableResolver) WebConsoleUtil.getVariableResolver(request);
        varResolver.put("__scriptConfig__",getScriptConfig());
        pw.println(TEMPLATE);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        final String contentType = getContentType(req);
        resp.setContentType(contentType);
        if (contentType.startsWith("text/")) {
            resp.setCharacterEncoding("UTF-8");
        }
        final String script = getCodeValue(req);
        final SlingBindings bindings = new SlingBindings();
        final PrintWriter pw = resp.getWriter();
        //Populate bindings
        bindings.put(SlingBindings.REQUEST, req);
        bindings.put(SlingBindings.READER, new StringReader(script));
        bindings.put(SlingBindings.RESPONSE, resp);
        bindings.put(SlingBindings.OUT, pw);

        //Also expose the bundleContext to simplify scripts interaction with the
        //enclosing OSGi container
        bindings.put("bundleContext", bundleContext);

        final String lang = WebConsoleUtil.getParameter(req, "lang");
        final Resource resource = new RuntimeScriptResource(lang, script);
        final boolean webClient = "webconsole".equals(WebConsoleUtil.getParameter(req,"client"));

        SlingScript slingScript = resource.adaptTo(SlingScript.class);
        try {
            log.debug("Executing script {}",script);
            slingScript.eval(bindings);
        } catch (Throwable t){
            if(!webClient){
                resp.setStatus(500);
            }
            pw.println(exceptionToString(t));
            log.warn("Error in executing script",t);
        }
    }

    private String getCodeValue(HttpServletRequest req) throws IOException {
        String script = WebConsoleUtil.getParameter(req, "code");
        if(script == null){
            script = getContentFromFilePart(req, "code");
        }
        if(script == null){
            throw new IllegalArgumentException("'code' parameter not passed");
        }
        return script;
    }

    private String getContentType(HttpServletRequest req) {
        String passedContentType = WebConsoleUtil.getParameter(req,"responseContentType");
        if(passedContentType != null){
            return passedContentType;
        }
        return req.getPathInfo().endsWith(".json") ? "application/json" : "text/plain";
    }

    private String exceptionToString(Throwable t) {
        StringWriter sw = new StringWriter();
        t.printStackTrace(new PrintWriter(sw));
        return sw.toString();
    }


    private static String[] processFileNames(String[] cssFiles) {
        String[] css = new String[cssFiles.length];
        for(int i = 0; i < cssFiles.length; i++){
            css[i] =  '/' + NAME + CSS[i];
        }
        return css;
    }

    private String getScriptConfig() {
        try {
            return getScriptConfig0();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private String getScriptConfig0() throws IOException {
        StringWriter sw = new StringWriter();
        JSONWriter jw = new JSONWriter(sw);
        jw.array();

        for(ScriptEngineFactory sef : scriptEngineManager.getEngineFactories()){
            jw.object();
            if(sef.getExtensions().isEmpty()){
                continue;
            }
            jw.key("langName").value(sef.getLanguageName());
            jw.key("langCode").value(sef.getExtensions().get(0));

            //Language mode as per CodeMirror names
            String mode = determineMode(sef.getExtensions());
            if(mode != null){
                jw.key("mode").value(mode);
            }

            jw.endObject();
        }

        jw.endArray();
        return sw.toString();
    }

    private String determineMode(List<String> extensions) {
        if(extensions.contains("groovy")){
            return "groovy";
        }else if (extensions.contains("esp")){
            return "javascript";
        }
        return null;
    }

    private String getContentFromFilePart(HttpServletRequest req, String paramName) throws IOException {
        String value = WebConsoleUtil.getParameter(req, paramName);
        if(value != null){
            return value;
        }
        final Map params = (Map) req.getAttribute( AbstractWebConsolePlugin.ATTR_FILEUPLOAD );
        if ( params == null ){
            return null;
        }
        FileItem[] codeFile = getFileItems(params,paramName);
        if(codeFile.length == 0){
            return null;
        }
        InputStream is = null;
        try{
            is = codeFile[0].getInputStream();
            StringWriter sw = new StringWriter();
            IOUtils.copy(is,sw,"utf-8");
            return sw.toString();
        }finally{
            IOUtils.closeQuietly(is);
        }
    }

    private FileItem[] getFileItems(Map params, String name) {
        final List files = new ArrayList();
        FileItem[] items = (FileItem[]) params.get(name);
        if (items != null) {
            for (int i = 0; i < items.length; i++) {
                if (!items[i].isFormField() && items[i].getSize() > 0) {
                    files.add(items[i]);
                }
            }
        }
        return (FileItem[]) files.toArray(new FileItem[files.size()]);
    }

    @Activate
    public void activate(BundleContext bundleContext) {
        super.activate(bundleContext);
        this.bundleContext = bundleContext;
    }

    @Deactivate
    public void deactivate() {
        super.deactivate();
    }
}
