package autotest.afe;

import autotest.afe.create.CreateJobViewPresenter.JobCreateListener;
import autotest.common.CustomHistory.HistoryToken;
import autotest.common.SimpleCallback;
import autotest.common.Utils;
import autotest.common.table.DataSource;
import autotest.common.table.DataSource.DataCallback;
import autotest.common.table.DataSource.Query;
import autotest.common.table.DataSource.SortDirection;
import autotest.common.table.DataTable;
import autotest.common.table.DatetimeSegmentFilter;
import autotest.common.table.DynamicTable;
import autotest.common.table.DynamicTable.DynamicTableListener;
import autotest.common.table.JSONObjectSet;
import autotest.common.table.RpcDataSource;
import autotest.common.table.SelectionManager;
import autotest.common.table.SimpleFilter;
import autotest.common.table.TableDecorator;
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.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
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.CheckBox;
import com.google.gwt.user.client.ui.TextBox;

import java.util.List;
import java.util.Map;
import java.util.Set;

public class HostDetailView extends DetailView implements DataCallback, TableActionsListener {
    private static final String[][] HOST_JOBS_COLUMNS = {
            {DataTable.WIDGET_COLUMN, ""}, {"type", "Type"}, {"job__id", "Job ID"},
            {"job_owner", "Job Owner"}, {"job_name", "Job Name"}, {"started_on", "Time started"},
            {"status", "Status"}
    };
    public static final int JOBS_PER_PAGE = 20;

    public interface HostDetailListener {
        public void onJobSelected(int jobId);
    }

    private static class HostQueueEntryDataSource extends RpcDataSource {
        public HostQueueEntryDataSource() {
            super("get_host_queue_entries", "get_num_host_queue_entries");
        }

        @Override
        protected List<JSONObject> handleJsonResult(JSONValue result) {
            List<JSONObject> resultArray = super.handleJsonResult(result);
            for (JSONObject row : resultArray) {
                // get_host_queue_entries() doesn't return type, so fill it in for consistency with
                // get_host_queue_entries_and_special_tasks()
                row.put("type", new JSONString("Job"));
            }
            return resultArray;
        }
    }

    private static class HostJobsTable extends DynamicTable {
        private static final DataSource normalDataSource = new HostQueueEntryDataSource();
        private static final DataSource dataSourceWithSpecialTasks =
            new RpcDataSource("get_host_queue_entries_and_special_tasks",
                              "get_num_host_queue_entries_and_special_tasks");

        private SimpleFilter hostFilter = new SimpleFilter();
        private String hostId;
        private String startTime;
        private String endTime;

        public HostJobsTable() {
            super(HOST_JOBS_COLUMNS, normalDataSource);
            addFilter(hostFilter);
        }

        public void setHostId(String hostId) {
            this.hostId = hostId;
            updateFilter();
        }

        public void setStartTime(String startTime) {
            this.startTime = startTime;
            updateFilter();
        }

        public void setEndTime(String endTime) {
            this.endTime = endTime;
            updateFilter();
        }

        private void updateFilter() {
            if (getDataSource() == normalDataSource) {
                sortOnColumn("job__id", SortDirection.DESCENDING);
            } else {
                clearSorts();
            }

            hostFilter.clear();
            hostFilter.setParameter("host",
                                    new JSONNumber(Double.parseDouble(hostId)));
            if (startTime != null && startTime != "")
                hostFilter.setParameter("start_time", new JSONString(startTime));
            if (endTime != null && endTime != "")
                hostFilter.setParameter("end_time", new JSONString(endTime));
        }

        public void setSpecialTasksEnabled(boolean enabled) {
            if (enabled) {
                setDataSource(dataSourceWithSpecialTasks);
            } else {
                setDataSource(normalDataSource);
            }

            updateFilter();
        }

        @Override
        protected void preprocessRow(JSONObject row) {
            JSONObject job = row.get("job").isObject();
            JSONString blank = new JSONString("");
            JSONString jobId = blank, owner = blank, name = blank;
            if (job != null) {
                int id = (int) job.get("id").isNumber().doubleValue();
                jobId = new JSONString(Integer.toString(id));
                owner = job.get("owner").isString();
                name = job.get("name").isString();
            }

            row.put("job__id", jobId);
            row.put("job_owner", owner);
            row.put("job_name", name);
        }
    }

    private String hostname = "";
    private String hostId = "";
    private DataSource hostDataSource = new HostDataSource();
    private HostJobsTable jobsTable = new HostJobsTable();
    private TableDecorator tableDecorator = new TableDecorator(jobsTable);
    private HostDetailListener hostDetailListener = null;
    private JobCreateListener jobCreateListener = null;
    private SelectionManager selectionManager;

    private JSONObject currentHostObject;

    private Button lockButton = new Button();
    private Button reverifyButton = new Button("Reverify");
    private Button reinstallButton = new Button("Reinstall");
    private Button repairButton = new Button("Repair");
    private CheckBox showSpecialTasks = new CheckBox();
    private DatetimeSegmentFilter startedTimeFilter = new DatetimeSegmentFilter();
    private TextBox hostnameInput = new TextBox();
    private Button hostnameFetchButton = new Button("Go");
    private TextBox lockReasonInput = new TextBox();

    public HostDetailView(HostDetailListener hostDetailListener,
                          JobCreateListener jobCreateListener) {
        this.hostDetailListener = hostDetailListener;
        this.jobCreateListener = jobCreateListener;
    }

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

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

    private String getFetchByHostnameControlsElementId() {
        return "view_host_fetch_by_hostname_controls";
    }

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

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

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

    @Override
    protected String getObjectId() {
        return hostId;
    }

    protected String getHostname() {
        return hostname;
    }

    @Override
    protected void setObjectId(String id) {
        if (id.length() == 0) {
            throw new IllegalArgumentException();
        }
        this.hostId = id;
    }

    @Override
    protected void fetchData() {
        JSONObject params = new JSONObject();
        params.put("id", new JSONString(getObjectId()));
        fetchDataCommmon(params);
    }

    private void fetchDataByHostname(String hostname) {
        JSONObject params = new JSONObject();
        params.put("hostname", new JSONString(hostname));
        fetchDataCommmon(params);
    }

    private void fetchDataCommmon(JSONObject params) {
        params.put("valid_only", JSONBoolean.getInstance(false));
        hostDataSource.query(params, this);
    }

    private void fetchByHostname(String hostname) {
        fetchDataByHostname(hostname);
        updateHistory();
    }

    @Override
    public void handleTotalResultCount(int totalCount) {}

    @Override
    public void onQueryReady(Query query) {
        query.getPage(null, null, null, this);
    }

    public void handlePage(List<JSONObject> data) {
        try {
            currentHostObject = Utils.getSingleObjectFromList(data);
        }
        catch (IllegalArgumentException exc) {
            NotifyManager.getInstance().showError("No such host found");
            resetPage();
            return;
        }

        setObjectId(currentHostObject.get("id").toString());

        String lockedText = Utils.jsonToString(currentHostObject.get(HostDataSource.LOCKED_TEXT));
        if (currentHostObject.get("locked").isBoolean().booleanValue()) {
            String lockedBy = Utils.jsonToString(currentHostObject.get("locked_by"));
            String lockedTime = Utils.jsonToString(currentHostObject.get("lock_time"));
            String lockReasonText = Utils.jsonToString(currentHostObject.get("lock_reason"));
            lockedText += ", by " + lockedBy + " on " + lockedTime;
            lockedText += ", reason: " + lockReasonText;
        }

        showField(currentHostObject, "status", "view_host_status");
        showField(currentHostObject, "platform", "view_host_platform");
        showField(currentHostObject, HostDataSource.HOST_ACLS, "view_host_acls");
        showField(currentHostObject, HostDataSource.OTHER_LABELS, "view_host_labels");
        showText(lockedText, "view_host_locked");
        String shard_url = Utils.jsonToString(currentHostObject.get("shard")).trim();
        String host_id = Utils.jsonToString(currentHostObject.get("id")).trim();
        if (shard_url.equals("<null>")){
            shard_url = "";
        } else {
            shard_url = "http://" + shard_url;
        }
        shard_url = shard_url + "/afe/#tab_id=view_host&object_id=" + host_id;
        showField(currentHostObject, "shard", "view_host_shard");
        getElementById("view_host_shard").setAttribute("href", shard_url);
        showField(currentHostObject, "protection", "view_host_protection");
        hostname = currentHostObject.get("hostname").isString().stringValue();
        String pageTitle = "Host " + hostname;
        hostnameInput.setText(hostname);
        updateLockButton();
        updateLockReasonInput();
        displayObjectData(pageTitle);

        jobsTable.setHostId(getObjectId());
        jobsTable.refresh();
    }

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

        // Replace fetch by id with fetch by hostname
        addWidget(hostnameInput, getFetchByHostnameControlsElementId());
        addWidget(hostnameFetchButton, getFetchByHostnameControlsElementId());

        hostnameInput.addKeyPressHandler(new KeyPressHandler() {
            public void onKeyPress (KeyPressEvent event) {
                if (event.getCharCode() == (char) KeyCodes.KEY_ENTER)
                    fetchByHostname(hostnameInput.getText());
            }
        });
        hostnameFetchButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                fetchByHostname(hostnameInput.getText());
            }
        });

        jobsTable.setRowsPerPage(JOBS_PER_PAGE);
        jobsTable.setClickable(true);
        jobsTable.addListener(new DynamicTableListener() {
            public void onRowClicked(int rowIndex, JSONObject row, boolean isRightClick) {
                if (isJobRow(row)) {
                    JSONObject job = row.get("job").isObject();
                    int jobId = (int) job.get("id").isNumber().doubleValue();
                    hostDetailListener.onJobSelected(jobId);
                } else {
                    String resultsPath = Utils.jsonToString(row.get("execution_path"));
                    Utils.openUrlInNewWindow(Utils.getRetrieveLogsUrl(resultsPath));
                }
            }

            public void onTableRefreshed() {}
        });
        tableDecorator.addPaginators();
        selectionManager = tableDecorator.addSelectionManager(false);
        jobsTable.setWidgetFactory(selectionManager);
        tableDecorator.addTableActionsPanel(this, true);
        tableDecorator.addControl("Show verifies, repairs, cleanups and resets",
                                  showSpecialTasks);
        tableDecorator.addFilter("Filter by time started:",
                                 startedTimeFilter);
        addWidget(tableDecorator, "view_host_jobs_table");

        showSpecialTasks.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                selectionManager.deselectAll();
                jobsTable.setSpecialTasksEnabled(showSpecialTasks.getValue());
                jobsTable.refresh();
            }
        });

        startedTimeFilter.addValueChangeHandler(
            new ValueChangeHandler() {
                public void onValueChange(ValueChangeEvent event) {
                    String value = (String) event.getValue();
                    jobsTable.setStartTime(value);
                    if (value == "")
                        startedTimeFilter.setStartTimeToPlaceHolderValue();
                    jobsTable.refresh();
                }
            },
            new ValueChangeHandler() {
                public void onValueChange(ValueChangeEvent event) {
                    String value = (String) event.getValue();
                    jobsTable.setEndTime(value);
                    if (value == "")
                        startedTimeFilter.setEndTimeToPlaceHolderValue();
                    jobsTable.refresh();
                }
            }
        );

        addWidget(lockButton, "view_host_lock_button");
        addWidget(lockReasonInput, "view_host_lock_reason_input");

        lockButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
               boolean locked = currentHostObject.get("locked").isBoolean().booleanValue();
               changeLock(!locked);
            }
        });
        lockReasonInput.addKeyPressHandler(new KeyPressHandler() {
            public void onKeyPress (KeyPressEvent event) {
                if (event.getCharCode() == (char) KeyCodes.KEY_ENTER) {
                    boolean locked = currentHostObject.get("locked").isBoolean().booleanValue();
                    changeLock(!locked);
                }
            }
        });

        reverifyButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                JSONObject params = new JSONObject();

                params.put("id", currentHostObject.get("id"));
                AfeUtils.callReverify(params, new SimpleCallback() {
                    public void doCallback(Object source) {
                       refresh();
                    }
                }, "Host " + hostname);
            }
        });
        addWidget(reverifyButton, "view_host_reverify_button");

        reinstallButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                JSONArray array = new JSONArray();
                array.set(0, new JSONString(hostname));
                AfeUtils.scheduleReinstall(array, hostname, jobCreateListener);
            }
        });
        addWidget(reinstallButton, "view_host_reinstall_button");

        repairButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                JSONObject params = new JSONObject();

                params.put("id", currentHostObject.get("id"));
                AfeUtils.callRepair(params, new SimpleCallback() {
                    public void doCallback(Object source) {
                       refresh();
                    }
                }, "Host " + hostname);
            }
        });
        addWidget(repairButton, "view_host_repair_button");
    }

    public void onError(JSONObject errorObject) {
        // RPC handler will display error
    }

    public ContextMenu getActionMenu() {
        ContextMenu menu = new ContextMenu();
        menu.addItem("Abort", new Command() {
            public void execute() {
                abortSelectedQueueEntriesAndSpecialTasks();
            }
        });
        if (selectionManager.isEmpty())
            menu.setEnabled(false);
        return menu;
    }

    private void abortSelectedQueueEntriesAndSpecialTasks() {
        Set<JSONObject> selectedEntries = selectionManager.getSelectedObjects();
        Set<JSONObject> selectedQueueEntries = new JSONObjectSet<JSONObject>();
        JSONArray selectedSpecialTaskIds = new JSONArray();
        for (JSONObject entry : selectedEntries) {
            if (isJobRow(entry))
                selectedQueueEntries.add(entry);
            else
                selectedSpecialTaskIds.set(selectedSpecialTaskIds.size(),
                                           entry.get("oid"));
        }
        if (!selectedQueueEntries.isEmpty()) {
            AfeUtils.abortHostQueueEntries(selectedQueueEntries, new SimpleCallback() {
                public void doCallback(Object source) {
                    refresh();
                }
            });
        }
        if (selectedSpecialTaskIds.size() > 0) {
            AfeUtils.abortSpecialTasks(selectedSpecialTaskIds, new SimpleCallback() {
                public void doCallback(Object source) {
                    refresh();
                }
            });
        }
    }

    private void updateLockButton() {
        boolean locked = currentHostObject.get("locked").isBoolean().booleanValue();
        if (locked) {
            lockButton.setText("Unlock");
        } else {
            lockButton.setText("Lock");
        }
    }

    private void updateLockReasonInput() {
        boolean locked = currentHostObject.get("locked").isBoolean().booleanValue();
        if (locked) {
            lockReasonInput.setText("");
            lockReasonInput.setEnabled(false);
        } else {
            lockReasonInput.setEnabled(true);
        }
    }

    private void changeLock(final boolean lock) {
        JSONArray hostIds = new JSONArray();
        hostIds.set(0, currentHostObject.get("id"));

        AfeUtils.changeHostLocks(hostIds, lock, lockReasonInput.getText(),
                                 "Host " + hostname, new SimpleCallback() {
            public void doCallback(Object source) {
                refresh();
            }
        });
    }

    private boolean isJobRow(JSONObject row) {
        String type = Utils.jsonToString(row.get("type"));
        return type.equals("Job");
    }

    public boolean isRowSelectable(JSONObject row) {
        return isJobRow(row);
    }

    @Override
    public void handleHistoryArguments(Map<String, String> arguments) {
        String hostname = arguments.get("hostname");
        String objectId = arguments.get("object_id");

        if (objectId != null) {
            try {
                updateObjectId(objectId);
            }
            catch (IllegalArgumentException exc) {
                return;
            }
        } else if (hostname != null) {
            fetchDataByHostname(hostname);
        } else {
            resetPage();
        }
    }
}
