package autotest.afe;

import autotest.common.JsonRpcCallback;
import autotest.common.SimpleCallback;
import autotest.common.StaticDataRepository;
import autotest.common.Utils;
import autotest.common.table.DataTable;
import autotest.common.table.DynamicTable;
import autotest.common.table.ListFilter;
import autotest.common.table.SearchFilter;
import autotest.common.table.SelectionManager;
import autotest.common.table.SimpleFilter;
import autotest.common.table.TableDecorator;
import autotest.common.table.DataTable.TableWidgetFactory;
import autotest.common.table.DynamicTable.DynamicTableListener;
import autotest.common.ui.ContextMenu;
import autotest.common.ui.DetailView;
import autotest.common.ui.NotifyManager;
import autotest.common.ui.TableActionsPanel.TableActionsListener;

import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONBoolean;
import com.google.gwt.json.client.JSONNumber;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONString;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DisclosurePanel;
import com.google.gwt.user.client.ui.Frame;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;

import java.util.Set;

public class JobDetailView extends DetailView implements TableWidgetFactory, TableActionsListener {
    private static final String[][] JOB_HOSTS_COLUMNS = {
        {DataTable.CLICKABLE_WIDGET_COLUMN, ""}, // selection checkbox
        {"hostname", "Host"}, {"full_status", "Status"},
        {"host_status", "Host Status"}, {"host_locked", "Host Locked"},
        // columns for status log and debug log links
        {DataTable.CLICKABLE_WIDGET_COLUMN, ""}, {DataTable.CLICKABLE_WIDGET_COLUMN, ""}
    };
    public static final String NO_URL = "about:blank";
    public static final int NO_JOB_ID = -1;
    public static final int HOSTS_PER_PAGE = 30;
    public static final String RESULTS_MAX_WIDTH = "700px";
    public static final String RESULTS_MAX_HEIGHT = "500px";

    public interface JobDetailListener {
        public void onHostSelected(String hostname);
        public void onCloneJob(JSONValue result);
        public void onCreateRecurringJob(int id);
    }

    protected int jobId = NO_JOB_ID;

    private JobStatusDataSource jobStatusDataSource = new JobStatusDataSource();
    protected DynamicTable hostsTable = new DynamicTable(JOB_HOSTS_COLUMNS, jobStatusDataSource);
    protected TableDecorator tableDecorator = new TableDecorator(hostsTable);
    protected SimpleFilter jobFilter = new SimpleFilter();
    protected Button abortButton = new Button("Abort job");
    protected Button cloneButton = new Button("Clone job");
    protected Button recurringButton = new Button("Create recurring job");
    protected Frame tkoResultsFrame = new Frame();

    protected JobDetailListener listener;
    private SelectionManager selectionManager;

    private Label controlFile = new Label();
    private DisclosurePanel controlFilePanel = new DisclosurePanel("");

    protected StaticDataRepository staticData = StaticDataRepository.getRepository();

    public JobDetailView(JobDetailListener listener) {
        this.listener = listener;
        setupSpreadsheetListener(Utils.getBaseUrl());
    }

    private native void setupSpreadsheetListener(String baseUrl) /*-{
        var ins = this;
        $wnd.onSpreadsheetLoad = function(event) {
            if (event.origin !== baseUrl) {
                return;
            }
            ins.@autotest.afe.JobDetailView::resizeResultsFrame(Ljava/lang/String;)(event.data);
        }

        $wnd.addEventListener("message", $wnd.onSpreadsheetLoad, false);
    }-*/;

    @SuppressWarnings("unused") // called from native
    private void resizeResultsFrame(String message) {
        String[] parts = message.split(" ");
        tkoResultsFrame.setSize(parts[0], parts[1]);
    }

    @Override
    protected void fetchData() {
        pointToResults(NO_URL, NO_URL, NO_URL, NO_URL, NO_URL);
        JSONObject params = new JSONObject();
        params.put("id", new JSONNumber(jobId));
        rpcProxy.rpcCall("get_jobs_summary", params, new JsonRpcCallback() {
            @Override
            public void onSuccess(JSONValue result) {
                JSONObject jobObject;
                try {
                    jobObject = Utils.getSingleObjectFromArray(result.isArray());
                }
                catch (IllegalArgumentException exc) {
                    NotifyManager.getInstance().showError("No such job found");
                    resetPage();
                    return;
                }
                String name = Utils.jsonToString(jobObject.get("name"));
                String runVerify = Utils.jsonToString(jobObject.get("run_verify"));

                showText(name, "view_label");
                showField(jobObject, "owner", "view_owner");
                String parent_job_url = Utils.jsonToString(jobObject.get("parent_job")).trim();
                if (parent_job_url.equals("<null>")){
                    parent_job_url = "http://www.youtube.com/watch?v=oHg5SJYRHA0";
                } else {
                    parent_job_url = "#tab_id=view_job&object_id=" + parent_job_url;
                }
                showField(jobObject, "parent_job", "view_parent");
                getElementById("view_parent").setAttribute("href", parent_job_url);
                showField(jobObject, "test_retry", "view_test_retry");
                double priorityValue = jobObject.get("priority").isNumber().getValue();
                String priorityName = staticData.getPriorityName(priorityValue);
                showText(priorityName, "view_priority");
                showField(jobObject, "created_on", "view_created");
                showField(jobObject, "timeout_mins", "view_timeout");
                String imageUrlString = "";
                if (jobObject.containsKey("image")) {
                    imageUrlString = Utils.jsonToString(jobObject.get("image")).trim();
                }
                showText(imageUrlString, "view_image_url");
                showField(jobObject, "max_runtime_mins", "view_max_runtime");
                showField(jobObject, "email_list", "view_email_list");
                showText(runVerify, "view_run_verify");
                showField(jobObject, "reboot_before", "view_reboot_before");
                showField(jobObject, "reboot_after", "view_reboot_after");
                showField(jobObject, "parse_failed_repair", "view_parse_failed_repair");
                showField(jobObject, "synch_count", "view_synch_count");
                showField(jobObject, "dependencies", "view_dependencies");

                if (staticData.getData("drone_sets_enabled").isBoolean().booleanValue()) {
                    showField(jobObject, "drone_set", "view_drone_set");
                }

                String header = Utils.jsonToString(jobObject.get("control_type")) + " control file";
                controlFilePanel.getHeaderTextAccessor().setText(header);
                controlFile.setText(Utils.jsonToString(jobObject.get("control_file")));

                JSONObject counts = jobObject.get("status_counts").isObject();
                String countString = AfeUtils.formatStatusCounts(counts, ", ");
                showText(countString, "view_status");
                abortButton.setVisible(isAnyEntryAbortable(counts));

                String jobTag = AfeUtils.getJobTag(jobObject);
                pointToResults(getResultsURL(jobId), getLogsURL(jobTag),
                               getOldResultsUrl(jobId), getTriageUrl(jobId),
                               getEmbeddedUrl(jobId));

                String jobTitle = "Job: " + name + " (" + jobTag + ")";
                displayObjectData(jobTitle);

                jobFilter.setParameter("job", new JSONNumber(jobId));
                hostsTable.refresh();
            }


            @Override
            public void onError(JSONObject errorObject) {
                super.onError(errorObject);
                resetPage();
            }
        });
    }

    protected boolean isAnyEntryAbortable(JSONObject statusCounts) {
        Set<String> statuses = statusCounts.keySet();
        for (String status : statuses) {
            if (!(status.equals("Completed") ||
                  status.equals("Failed") ||
                  status.equals("Stopped") ||
                  status.startsWith("Aborted"))) {
                return true;
            }
        }
        return false;
    }

    @Override
    public void initialize() {
        super.initialize();

        idInput.setVisibleLength(5);

        hostsTable.setRowsPerPage(HOSTS_PER_PAGE);
        hostsTable.setClickable(true);
        hostsTable.addListener(new DynamicTableListener() {
            public void onRowClicked(int rowIndex, JSONObject row, boolean isRightClick) {
                JSONObject host = row.get("host").isObject();
                String hostname = host.get("hostname").isString().stringValue();
                listener.onHostSelected(hostname);
            }

            public void onTableRefreshed() {}
        });
        hostsTable.setWidgetFactory(this);

        tableDecorator.addPaginators();
        addTableFilters();
        selectionManager = tableDecorator.addSelectionManager(false);
        tableDecorator.addTableActionsPanel(this, true);
        addWidget(tableDecorator, "job_hosts_table");

        abortButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                abortJob();
            }
        });
        addWidget(abortButton, "view_abort");

        cloneButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                cloneJob();
            }
        });
        addWidget(cloneButton, "view_clone");

        recurringButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                createRecurringJob();
            }
        });
        addWidget(recurringButton, "view_recurring");

        tkoResultsFrame.getElement().setAttribute("scrolling", "no");
        addWidget(tkoResultsFrame, "tko_results");

        controlFile.addStyleName("code");
        controlFilePanel.setContent(controlFile);
        addWidget(controlFilePanel, "view_control_file");

        if (!staticData.getData("drone_sets_enabled").isBoolean().booleanValue()) {
            AfeUtils.removeElement("view_drone_set_wrapper");
        }
    }

    protected void addTableFilters() {
        hostsTable.addFilter(jobFilter);

        SearchFilter hostnameFilter = new SearchFilter("host__hostname", true);
        ListFilter statusFilter = new ListFilter("status");
        StaticDataRepository staticData = StaticDataRepository.getRepository();
        JSONArray statuses = staticData.getData("job_statuses").isArray();
        statusFilter.setChoices(Utils.JSONtoStrings(statuses));

        tableDecorator.addFilter("Hostname", hostnameFilter);
        tableDecorator.addFilter("Status", statusFilter);
    }

    private void abortJob() {
        JSONObject params = new JSONObject();
        params.put("job__id", new JSONNumber(jobId));
        AfeUtils.callAbort(params, new SimpleCallback() {
            public void doCallback(Object source) {
                refresh();
            }
        });
    }

    private void abortSelectedHosts() {
        AfeUtils.abortHostQueueEntries(selectionManager.getSelectedObjects(), new SimpleCallback() {
            public void doCallback(Object source) {
                refresh();
            }
        });
    }

    protected void cloneJob() {
        ContextMenu menu = new ContextMenu();
        menu.addItem("Reuse any similar hosts  (default)", new Command() {
            public void execute() {
                cloneJob(false);
            }
        });
        menu.addItem("Reuse same specific hosts", new Command() {
            public void execute() {
                cloneJob(true);
            }
        });
        menu.addItem("Use failed and aborted hosts", new Command() {
            public void execute() {
                JSONObject queueEntryFilterData = new JSONObject();
                String sql = "(status = 'Failed' OR aborted = TRUE OR " +
                             "(host_id IS NULL AND meta_host IS NULL))";

                queueEntryFilterData.put("extra_where", new JSONString(sql));
                cloneJob(true, queueEntryFilterData);
            }
        });

        menu.showAt(cloneButton.getAbsoluteLeft(),
                cloneButton.getAbsoluteTop() + cloneButton.getOffsetHeight());
    }

    private void cloneJobOnSelectedHosts() {
        Set<JSONObject> hostsQueueEntries = selectionManager.getSelectedObjects();
        JSONArray queueEntryIds = new JSONArray();
        for (JSONObject queueEntry : hostsQueueEntries) {
          queueEntryIds.set(queueEntryIds.size(), queueEntry.get("id"));
        }

        JSONObject queueEntryFilterData = new JSONObject();
        queueEntryFilterData.put("id__in", queueEntryIds);
        cloneJob(true, queueEntryFilterData);
    }

    private void cloneJob(boolean preserveMetahosts) {
        cloneJob(preserveMetahosts, new JSONObject());
    }

    private void cloneJob(boolean preserveMetahosts, JSONObject queueEntryFilterData) {
        JSONObject params = new JSONObject();
        params.put("id", new JSONNumber(jobId));
        params.put("preserve_metahosts", JSONBoolean.getInstance(preserveMetahosts));
        params.put("queue_entry_filter_data", queueEntryFilterData);

        rpcProxy.rpcCall("get_info_for_clone", params, new JsonRpcCallback() {
            @Override
            public void onSuccess(JSONValue result) {
                listener.onCloneJob(result);
            }
        });
    }

    private void createRecurringJob() {
        listener.onCreateRecurringJob(jobId);
    }

    private String getResultsURL(int jobId) {
        return "/new_tko/#tab_id=spreadsheet_view&row=hostname&column=test_name&" +
               "condition=afe_job_id+%253d+" + Integer.toString(jobId) + "&" +
               "show_incomplete=true";
    }

    private String getOldResultsUrl(int jobId) {
        return "/tko/compose_query.cgi?" +
               "columns=test&rows=hostname&condition=tag%7E%27" +
               Integer.toString(jobId) + "-%25%27&title=Report";
    }

    private String getTriageUrl(int jobId) {
        /*
         * Having a hard-coded path like this is very unfortunate, but there's no simple way
         * in the current design to generate this link by code.
         *
         * TODO: Redesign the system so that we can generate these links by code.
         *
         * Idea: Be able to instantiate a TableView object, ask it to set up to triage this job ID,
         *       and then ask it for the history URL.
         */

        return "/new_tko/#tab_id=table_view&columns=test_name%252Cstatus%252Cgroup_count%252C" +
               "reason&sort=test_name%252Cstatus%252Creason&condition=afe_job_id+%253D+" + jobId +
               "+AND+status+%253C%253E+%2527GOOD%2527&show_invalid=false";
    }

    private String getEmbeddedUrl(int jobId) {
        return "/embedded_spreadsheet/EmbeddedSpreadsheetClient.html?afe_job_id=" + jobId;
    }

    /**
     * Get the path for a job's raw result files.
     * @param jobLogsId id-owner, e.g. "172-showard"
     */
    protected String getLogsURL(String jobLogsId) {
        return Utils.getRetrieveLogsUrl(jobLogsId);
    }

    protected void pointToResults(String resultsUrl, String logsUrl,
                                  String oldResultsUrl, String triageUrl,
                                  String embeddedUrl) {
        getElementById("results_link").setAttribute("href", resultsUrl);
        getElementById("old_results_link").setAttribute("href", oldResultsUrl);
        getElementById("raw_results_link").setAttribute("href", logsUrl);
        getElementById("triage_failures_link").setAttribute("href", triageUrl);

        tkoResultsFrame.setSize(RESULTS_MAX_WIDTH, RESULTS_MAX_HEIGHT);
        if (!resultsUrl.equals(NO_URL)) {
            updateResultsFrame(tkoResultsFrame.getElement(), embeddedUrl);
        }
    }

    private native void updateResultsFrame(Element frame, String embeddedUrl) /*-{
        // Use location.replace() here so that the frame's URL changes don't show up in the browser
        // window's history
        frame.contentWindow.location.replace(embeddedUrl);
    }-*/;

    @Override
    protected String getNoObjectText() {
        return "No job selected";
    }

    @Override
    protected String getFetchControlsElementId() {
        return "job_id_fetch_controls";
    }

    @Override
    protected String getDataElementId() {
        return "view_data";
    }

    @Override
    protected String getTitleElementId() {
        return "view_title";
    }

    @Override
    protected String getObjectId() {
        if (jobId == NO_JOB_ID) {
            return NO_OBJECT;
        }
        return Integer.toString(jobId);
    }

    @Override
    public String getElementId() {
        return "view_job";
    }

    @Override
    protected void setObjectId(String id) {
        int newJobId;
        try {
            newJobId = Integer.parseInt(id);
        }
        catch (NumberFormatException exc) {
            throw new IllegalArgumentException();
        }
        this.jobId = newJobId;
    }

    public Widget createWidget(int row, int cell, JSONObject hostQueueEntry) {
        if (cell == 0) {
            return selectionManager.createWidget(row, cell, hostQueueEntry);
        }

        String executionSubdir = Utils.jsonToString(hostQueueEntry.get("execution_subdir"));
        if (executionSubdir.equals("")) {
            // when executionSubdir == "", it's a job that hasn't yet run.
            return null;
        }

        JSONObject jobObject = hostQueueEntry.get("job").isObject();
        String owner = Utils.jsonToString(jobObject.get("owner"));
        String basePath = jobId + "-" + owner + "/" + executionSubdir + "/";

        if (cell == JOB_HOSTS_COLUMNS.length - 1) {
            return new HTML(getLogsLinkHtml(basePath + "debug", "Debug logs"));
        } else {
            return new HTML(getLogsLinkHtml(basePath + "status.log", "Status log"));
        }
    }

    private String getLogsLinkHtml(String url, String text) {
        url = Utils.getRetrieveLogsUrl(url);
        return "<a target=\"_blank\" href=\"" + url + "\">" + text + "</a>";
    }

    public ContextMenu getActionMenu() {
        ContextMenu menu = new ContextMenu();

        menu.addItem("Abort hosts", new Command() {
            public void execute() {
                abortSelectedHosts();
            }
        });

        menu.addItem("Clone job on selected hosts", new Command() {
            public void execute() {
                cloneJobOnSelectedHosts();
            }
        });

        return menu;
    }
}
