package org.apache.sling.tail.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 ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.FileAppender;
import org.apache.felix.scr.annotations.*;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.utils.json.JSONWriter;
import org.apache.felix.webconsole.AbstractWebConsolePlugin;
import org.apache.felix.webconsole.WebConsoleConstants;
import org.apache.sling.tail.LogFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.util.*;

/**
 *
 */
@Component
@Service(value = { Servlet.class })
@Properties({
        @Property(name=org.osgi.framework.Constants.SERVICE_DESCRIPTION,
                value="Apache Sling Web Console Plugin to tail log(s) of this Sling instance"),
        @Property(name= WebConsoleConstants.PLUGIN_LABEL, value=LogTailerWebConsolePlugin.LABEL),
        @Property(name=WebConsoleConstants.PLUGIN_TITLE, value=LogTailerWebConsolePlugin.TITLE),
        @Property(name="felix.webconsole.configprinter.modes", value={"always"})
})
public class LogTailerWebConsolePlugin extends AbstractWebConsolePlugin {
    public static final String LABEL = "tail";
    public static final String TITLE = "Tail Logs";

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    private static final int LINES_TO_TAIL = 100;
    private static final String POSITION_COOKIE = "log.tail.position";
    private static final String FILTER_COOKIE = "log.tail.filter";
    private static final String MODIFIED_COOKIE = "log.modified";
    private static final String CREATED_COOKIE = "log.created";

    private String fileName = "";
    private File errLog;

    @Override
    protected void renderContent(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        if(isAjaxRequest(request)) {

            parseCommand(request, response);

            RandomAccessFile randomAccessFile = null;

            try {

                try {
                    randomAccessFile = new RandomAccessFile(errLog, "r");
                    log.debug("Tailing file " + fileName + " of length " + randomAccessFile.length());
                } catch (Exception e) {
                    log.error("Error reading " + fileName, e);
                    response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                    return;
                }

                JSONWriter json = new JSONWriter(response.getWriter());
                json.object();

                boolean reverse = false;
                //long created = getCreatedTimestampFromCookie(request);
            /*long modified = getModifiedTimestampFromCookie(request);
            if(errLog.lastModified() == modified) {
                json.endObject();
                return;
            }
            else {
                 persistCookie(response, MODIFIED_COOKIE, String.valueOf(errLog.lastModified()));
            }*/
                long pos = getPositionFromCookie(request);
                if(pos < 0) {
                    pos = randomAccessFile.length()-1;
                    reverse = true;
                }
                else if(pos > randomAccessFile.length()) {//file rotated
                    pos = 0;
                }
                LogFilter[] query = getQueryFromCookie(request);

                if(reverse) {
                    randomAccessFile.seek(pos);
                    if(randomAccessFile.read() == '\n') {
                        pos--;
                        randomAccessFile.seek(pos);
                        if(randomAccessFile.read() == '\r') {
                            pos--;
                        }
                    }

                    json.key("content").array();
                    int found = 0;
                    StringBuilder sb = new StringBuilder();
                    String line = null;
                    List<String> lines = new ArrayList<String>();
                    while(found != LINES_TO_TAIL && pos > 0) {
                        boolean eol = false;
                        randomAccessFile.seek(pos);
                        int c = randomAccessFile.read();
                        if(c == '\n') {
                            found++;
                            sb = sb.reverse();
                            line = sb.toString();
                            sb = new StringBuilder();
                            eol = true;
                            pos--;
                            if(pos > 0) {
                                randomAccessFile.seek(pos);
                                if(randomAccessFile.read() == '\r') {
                                    pos--;
                                }
                            }
                        }
                        else {
                            sb.append((char)c);
                            pos--;
                        }

                        if(eol) {
                            if(filter(line, query)){
                                lines.add(line);
                            }
                        }
                    }

                    if(pos < 0) {
                        if(filter(line, query)){
                            lines.add(line);
                        }
                    }
                    for(int i=lines.size()-1; i > -1; i--) {
                        json.object().key("line").value(lines.get(i)).endObject();
                    }
                    json.endArray();
                    json.endObject();
                }
                else {
                    randomAccessFile.seek(pos);
                    String line = null;
                    int lineCount = 0;
                    json.key("content").array();
                    boolean read = true;
                    while(read) {
                        StringBuilder input = new StringBuilder();
                        int c = -1;
                        boolean eol = false;

                        while (!eol) {
                            switch (c = randomAccessFile.read()) {
                                case -1:
                                case '\n':
                                    eol = true;
                                    break;
                                case '\r':
                                    eol = true;
                                    long cur = randomAccessFile.getFilePointer();
                                    if ((randomAccessFile.read()) != '\n') {
                                        randomAccessFile.seek(cur);
                                    }
                                    break;
                                default:
                                    input.append((char)c);
                                    break;
                            }
                        }

                        if ((c == -1) && (input.length() == 0)) {
                            read = false;
                            continue;
                        }
                        line = input.toString();
                        lineCount++;
                        if(lineCount == LINES_TO_TAIL) {
                            read = false;
                        }
                        pos = randomAccessFile.getFilePointer();

                        if(filter(line, query)){
                            json.object().key("line").value(line).endObject();
                        }
                    }
                    json.endArray();
                    json.endObject();
                }

                persistCookie(response, POSITION_COOKIE, String.valueOf(randomAccessFile.getFilePointer()));

            } catch (Exception e) {
                log.error("Error tailing " + fileName, e);
                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            }
            finally {
                try {
                    if(randomAccessFile != null) {
                        randomAccessFile.close();
                    }
                }
                catch (Exception e) {
                    log.error("Error closing " + fileName, e);
                }
            }
        }
        else {
            PrintWriter printWriter = response.getWriter();
            printWriter.println("<script type=\"text/javascript\" src=\"/libs/sling/logtail-plugin/js/tail.js\"></script>");
            printWriter.println("<link href=\"/libs/sling/logtail-plugin/css/tail.css\" rel=\"stylesheet\" type=\"text/css\"></link>");
            printWriter.println("<div class=\"header-cont\">");
            printWriter.println("   <div class=\"header\" style=\"display:none;\">");
            printWriter.println("       <table>");
            printWriter.println("           <tr>");
            printWriter.println("               <td><button class=\"numbering\" title=\"Show Line Numbers\" data-numbers=\"false\">Show Line No.</button></td>");
            printWriter.println("               <td><button class=\"pause\" title=\"Pause\">Pause</button></td>");
            printWriter.println("               <td class=\"longer\"><label>Sync frequency(msec)</label>");
            printWriter.println("                   <button class=\"faster\" title=\"Sync Faster\">-</button>");
            printWriter.println("                   <input id=\"speed\" type=\"text\" value=\"3000\"/>");
            printWriter.println("                   <button class=\"slower\" title=\"Sync Slower\">+</button></td>");
            printWriter.println("               <td><button class=\"tail\" title=\"Unfollow Tail\" data-following=\"true\">Unfollow</button></td>");
            printWriter.println("               <td><button class=\"highlighting\" title=\"Highlight\">Highlight</button></td>");
            printWriter.println("               <td><button class=\"clear\" title=\"Clear Display\">Clear</button></td>");
            printWriter.println("               <td class=\"longer\"><input id=\"filter\" type=\"text\"/><span class=\"filterClear ui-icon ui-icon-close\" title=\"Clear Filter\">&nbsp;</span><button class=\"filter\" title=\"Filter Logs\">Filter</button></td>");
            printWriter.println("               <td><button class=\"refresh\" title=\"Reload Logs\">Reload</button></td>");
            printWriter.println("               <td><button class=\"sizeplus\" title=\"Bigger\">a->A</button></td>");
            printWriter.println("               <td><button class=\"sizeminus\" title=\"Smaller\">A->a</button></td>");
            printWriter.println("               <td><button class=\"top\" title=\"Scroll to Top\">Top</button></td>");
            printWriter.println("               <td><button class=\"bottom\" title=\"Scroll to Bottom\">Bottom</button></td>");
            printWriter.println("           </tr>");
            printWriter.println("           <tr>");
            printWriter.println("               <td class=\"loadingstatus\" colspan=\"2\" data-status=\"inactive\"><ul><li></li></ul></td>");
            printWriter.println("               <td>Tailing &nbsp; <select id=\"logfiles\">" + getOptions() + "</select></td>");
            printWriter.println("           </tr>");
            printWriter.println("       </table>");
            printWriter.println("   </div>");
            printWriter.println("   <div class=\"pulldown\" title=\"Click to show options\">&nbsp;==&nbsp;</div>");
            printWriter.println("</div>");
            printWriter.println("");
            printWriter.println("   <div class=\"content\">");
            printWriter.println("");
            printWriter.println("       <div id=\"logarea\"></div>");
            printWriter.println("");
            printWriter.println("   </div>");
        }
    }

    protected void parseCommand(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String cmd = request.getParameter("command");
        if(cmd == null) {
            return;
        }

        if(cmd.equals("reset")) {
            deleteCookie(response, FILTER_COOKIE);
        }
        else if(cmd.startsWith("filter:")) {
            String queryStr = cmd.substring(7);
            if(queryStr.length()==0) {
                deleteCookie(response, FILTER_COOKIE);
            }
            else {
                persistCookie(response, FILTER_COOKIE, queryStr);
                log.info("Filtering on : " + queryStr);
            }
        }
        else if(cmd.startsWith("file:")) {
            if(!fileName.equals(cmd.substring(5))) {
                deleteCookie(response, FILTER_COOKIE);
                deleteCookie(response, POSITION_COOKIE);
                fileName = cmd.substring(5);
                errLog = new File(filePathMap.get(fileName));
                if(!errLog.exists()) {
                    throw new ServletException("File " + fileName + " doesn't exist");
                }
                if(!errLog.canRead()) {
                    throw new ServletException("Cannot read file " + fileName);
                }
            }
        }
    }

    @Override
    public String getLabel() {
        return LABEL;
    }

    @Override
    public String getTitle() {
        return TITLE;
    }

    private HashMap<String, String> filePathMap = new HashMap<String, String>();

    private String getKey(File file) {
        if(!filePathMap.containsKey(file.getName())) {
            filePathMap.put(file.getName(), file.getAbsolutePath());
        }
        return file.getName();
    }

    private String getOptions() {
        Set<String> logFiles = new HashSet<String>();
        LoggerContext context = (LoggerContext)LoggerFactory.getILoggerFactory();
        for (ch.qos.logback.classic.Logger logger : context.getLoggerList()) {
            for (Iterator<Appender<ILoggingEvent>> index = logger.iteratorForAppenders(); index.hasNext();) {
                Appender<ILoggingEvent> appender = index.next();
                if(appender instanceof FileAppender) {
                    FileAppender fileAppender = (FileAppender) appender;
                    String logfilePath = fileAppender.getFile();
                    logFiles.add(logfilePath);
                }
            }
        }

        String logFilesHtml = "<option value=\"\"> - Select file - </option>";
        for(String logFile : logFiles) {
            File file = new File(logFile);
            logFilesHtml += "<option value=\"" + getKey(file) + "\">" + file.getName() + "</option>";
        }
        return logFilesHtml;
    }

    @Override
    protected boolean isHtmlRequest( final HttpServletRequest request ) {
        return !isAjaxRequest(request);
    }

    private boolean isAjaxRequest( final HttpServletRequest request) {
        return "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));
    }

    private boolean filter(String str, LogFilter[] query) {
        if(query != null) {
            for(LogFilter q : query) {
                if(!q.eval(str)) {
                    return false;
                }
            }
        }
        return true;
    }

    private void deleteCookie(HttpServletResponse response, String name) {
        Cookie cookie = new Cookie(name, "");
        cookie.setMaxAge(0);
        response.addCookie(cookie);
        log.debug("Deleting cookie :: " + cookie.getName());
    }

    private void persistCookie(HttpServletResponse response, String name, String value) {
        Cookie cookie = new Cookie(name , value);
        //cookie.setPath("/system/console/" + LABEL);
        response.addCookie(cookie);
        log.debug("Adding cookie :: " + cookie.getName() + " " + cookie.getValue());
    }

    private LogFilter[] getQueryFromCookie(HttpServletRequest request) {
        try {
            for(Cookie cookie : request.getCookies()) {
                if(cookie.getName().equals(FILTER_COOKIE)) {
                    String[] parts = cookie.getValue().split("&&");
                    LogFilter[] conditions = new LogFilter[parts.length];
                    for(int i=0; i<parts.length; i++) {
                        final String part = parts[i];
                        conditions[i] = new LogFilter() {
                            public boolean eval(String input) {
                                return input.contains(part);
                            }

                            public String toString() {
                                return part;
                            }
                        };
                    }
                    return conditions;
                }
            }
        }
        catch (Exception e) {

        }
        return null;
    }

    private long getCreatedTimestampFromCookie(HttpServletRequest request) {
        try {
            for(Cookie cookie : request.getCookies()) {
                if(cookie.getName().equals(CREATED_COOKIE)) {
                    return Long.parseLong(cookie.getValue());
                }
            }
        }
        catch (Exception e) {

        }
        return -1;
    }

    private long getModifiedTimestampFromCookie(HttpServletRequest request) {
        try {
            for(Cookie cookie : request.getCookies()) {
                if(cookie.getName().equals(MODIFIED_COOKIE)) {
                    return Long.parseLong(cookie.getValue());
                }
            }
        }
        catch (Exception e) {

        }
        return -1;
    }

    private long getPositionFromCookie(HttpServletRequest request) {
        try {
            for(Cookie cookie : request.getCookies()) {
                if(cookie.getName().equals(POSITION_COOKIE)) {
                    return Long.parseLong(cookie.getValue());
                }
            }
        }
        catch (Exception e) {
            log.debug("Position specified is invalid, Tailing from beginning of the file.", e);
        }
        return -1;
    }
}
