/*
 * 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.distribution.journal.impl.shared;

import java.io.IOException;
import java.io.PrintWriter;
import java.time.Duration;
import java.util.List;
import java.util.Optional;

import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.felix.webconsole.AbstractWebConsolePlugin;
import org.apache.felix.webconsole.WebConsoleConstants;
import org.apache.sling.distribution.journal.FullMessage;
import org.apache.sling.distribution.journal.messages.Messages.PackageMessage;
import org.apache.sling.distribution.journal.messages.Messages.PackageMessage.ReqType;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(service = Servlet.class,
        property = {
        Constants.SERVICE_DESCRIPTION + "=" + "Package viewer for content distribution",
        WebConsoleConstants.PLUGIN_LABEL + "=" + PackageViewerPlugin.LABEL,
        WebConsoleConstants.PLUGIN_TITLE + "=" + PackageViewerPlugin.TITLE
})
public class PackageViewerPlugin extends AbstractWebConsolePlugin {
    private static final Duration BROWSE_TIMEOUT = Duration.ofMillis(1000);
    private static final Duration DOWNLOAD_TIMEOUT = Duration.ofMillis(20000);
    private static final int NOT_FOUND = 404;
    private static final int MAX_NUM_MESSAGES = 100;
    private static final long serialVersionUID = -3113699912185558439L;
    protected static final String LABEL = "distpackages";
    protected static final String TITLE = "Distribution Package Viewer";

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

    @Reference
    PackageBrowser packageBrowser; //NOSONAR
    
    @Override
    public String getLabel() {
        return LABEL;
    }

    @Override
    public String getTitle() {
        return TITLE;
    }

    @Override
    public String getCategory() {
        return "Sling";
    }
    
    @Override
    protected void renderContent(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {
        Optional<Long> offset = getOffset(req);
        if (!offset.isPresent()) {
            String startOffsetSt = req.getParameter("startOffset");
            long startOffset = startOffsetSt != null ? new Long(startOffsetSt) : 0;
            renderPackageList(startOffset, res.getWriter());
        } else {
            writePackage(offset.get(), res);
        }
    }

    private void renderPackageList(long startOffset, PrintWriter writer) {
        writer.println("<table class=\"tablesorter nicetable noauto\">");
        writer.println("<tr><th>Id</th><th>Offset</th><th>Type</th><th>Paths</th></tr>");
        List<FullMessage<PackageMessage>> msgs = packageBrowser.getMessages(startOffset, MAX_NUM_MESSAGES, BROWSE_TIMEOUT);
        msgs.stream().filter(this::notTestMessage).map(this::writeMsg).forEach(writer::println);
        writer.println("</table>");
        if (msgs.size() == MAX_NUM_MESSAGES) {
            FullMessage<PackageMessage> lastMsg = msgs.get(msgs.size() - 1);
            long nextOffset = lastMsg.getInfo().getOffset() + 1;
            writer.println(String.format("<p><a href =\"%s?startOffset=%d\">next page</a>",
                    LABEL,
                    nextOffset));
        }
    }

    private String writeMsg(FullMessage<PackageMessage> msg) {
        return String.format("<tr><td><a href=\"%s/%d\">%s</a></td><td>%d</td><td>%s</td><td>%s</td></tr>",
                LABEL,
                msg.getInfo().getOffset(),
                msg.getMessage().getPkgId(),
                msg.getInfo().getOffset(),
                msg.getMessage().getReqType(),
                msg.getMessage().getPathsList().toString());
    }

    private void writePackage(Long offset, HttpServletResponse res) throws IOException {
        log.info("Retrieving package with offset {}", offset);
        List<FullMessage<PackageMessage>> msgs = packageBrowser.getMessages(offset, 1, DOWNLOAD_TIMEOUT);
        if (!msgs.isEmpty()) {
            PackageMessage msg = msgs.iterator().next().getMessage();
            res.setHeader("Content-Type", "application/octet-stream");
            String filename = msg.getPkgId() + ".zip";
            res.setHeader("Content-Disposition" , "inline; filename=\"" + filename + "\"");
            packageBrowser.writeTo(msg, res.getOutputStream());
        } else {
            res.setStatus(NOT_FOUND);
        }
    }
    
    @Override
    protected boolean isHtmlRequest(HttpServletRequest request) {
        return !getOffset(request).isPresent();
    }

    private Optional<Long> getOffset(HttpServletRequest req) {
        int startIndex = LABEL.length() + 2;
        if (startIndex <= req.getPathInfo().length()) {
            String offsetSt = req.getPathInfo().substring(startIndex);
            return Optional.of(new Long(offsetSt));
        } else {
            return Optional.empty();
        }
    }

    private boolean notTestMessage(FullMessage<PackageMessage> msg) {
        return msg.getMessage().getReqType() != ReqType.TEST;
    }
    

}