1package autotest.tko;
2
3import autotest.common.JsonRpcCallback;
4import autotest.common.JsonRpcProxy;
5import autotest.common.SimpleCallback;
6import autotest.common.StaticDataRepository;
7import autotest.common.Utils;
8import autotest.common.ui.NotifyManager;
9
10import com.google.gwt.event.dom.client.ClickEvent;
11import com.google.gwt.event.dom.client.ClickHandler;
12import com.google.gwt.json.client.JSONObject;
13import com.google.gwt.json.client.JSONString;
14import com.google.gwt.json.client.JSONValue;
15import com.google.gwt.user.client.ui.Anchor;
16import com.google.gwt.user.client.ui.Button;
17import com.google.gwt.user.client.ui.DialogBox;
18import com.google.gwt.user.client.ui.HTML;
19import com.google.gwt.user.client.ui.HorizontalPanel;
20import com.google.gwt.user.client.ui.ListBox;
21import com.google.gwt.user.client.ui.Panel;
22import com.google.gwt.user.client.ui.StackPanel;
23import com.google.gwt.user.client.ui.TextBox;
24import com.google.gwt.user.client.ui.VerticalPanel;
25
26public class TestLabelManager implements ClickHandler {
27    public static final String INVALIDATED_LABEL = "invalidated";
28    private static final String ADD_TEXT = "Add label";
29    private static final String REMOVE_TEXT = "Remove label";
30    private static final int STACK_SELECT = 0, STACK_CREATE = 1;
31
32    private static final TestLabelManager theInstance = new TestLabelManager();
33
34    private static final JsonRpcProxy rpcProxy = JsonRpcProxy.getProxy();
35    private static NotifyManager notifyManager = NotifyManager.getInstance();
36    private static StaticDataRepository staticData = StaticDataRepository.getRepository();
37
38    private DialogBox selectLabelDialog = new DialogBox(false, true); // modal
39    private ListBox labelList = new ListBox();
40    private TextBox newLabelName = new TextBox();
41    private Anchor createLabelLink, cancelCreateLink;
42    private StackPanel stack = new StackPanel();
43    private Button submitButton = new Button(), cancelButton = new Button("Cancel");
44
45    private JSONObject currentTestCondition;
46
47
48    private TestLabelManager() {
49        createLabelLink = new Anchor("Create new label");
50        cancelCreateLink = new Anchor("Cancel create label");
51        ClickHandler linkListener = new ClickHandler() {
52            public void onClick(ClickEvent event) {
53                if (event.getSource() == createLabelLink) {
54                    stack.showStack(STACK_CREATE);
55                } else {
56                    stack.showStack(STACK_SELECT);
57                }
58            }
59        };
60        createLabelLink.addClickHandler(linkListener);
61        cancelCreateLink.addClickHandler(linkListener);
62
63        Panel selectPanel = new VerticalPanel();
64        selectPanel.add(new HTML("Select label:"));
65        selectPanel.add(labelList);
66        selectPanel.add(createLabelLink);
67        stack.add(selectPanel);
68
69        Panel createPanel = new VerticalPanel();
70        createPanel.add(new HTML("Enter label name:"));
71        createPanel.add(newLabelName);
72        createPanel.add(cancelCreateLink);
73        stack.add(createPanel);
74
75        Panel buttonPanel = new HorizontalPanel();
76        buttonPanel.add(submitButton);
77        buttonPanel.add(cancelButton);
78
79        Panel dialogPanel = new VerticalPanel();
80        dialogPanel.add(stack);
81        dialogPanel.add(buttonPanel);
82        selectLabelDialog.add(dialogPanel);
83
84        submitButton.addClickHandler(this);
85        cancelButton.addClickHandler(this);
86    }
87
88    public static TestLabelManager getManager() {
89        return theInstance;
90    }
91
92    private void setLinksVisible(boolean visible) {
93        createLabelLink.setVisible(visible);
94        cancelCreateLink.setVisible(visible);
95    }
96
97    public void handleAddLabels(JSONObject testCondition) {
98        currentTestCondition = testCondition;
99        newLabelName.setText("");
100
101        String[] labels = Utils.JSONObjectsToStrings(staticData.getData("test_labels").isArray(),
102                                                     "name");
103        if (labels.length == 0) {
104            setLinksVisible(false);
105            stack.showStack(STACK_CREATE);
106        } else {
107            setLinksVisible(true);
108            stack.showStack(STACK_SELECT);
109            populateLabelList(labels);
110        }
111        showDialog(ADD_TEXT);
112    }
113
114    public void handleRemoveLabels(JSONObject testCondition) {
115        currentTestCondition = testCondition;
116
117        rpcProxy.rpcCall("get_test_labels_for_tests", currentTestCondition, new JsonRpcCallback() {
118            @Override
119            public void onSuccess(JSONValue result) {
120                String[] labels = Utils.JSONObjectsToStrings(result.isArray(), "name");
121                if (labels.length == 0) {
122                    notifyManager.showMessage("No labels on selected tests");
123                    return;
124                }
125                populateLabelList(labels);
126                setLinksVisible(false);
127                stack.showStack(STACK_SELECT);
128                showDialog(REMOVE_TEXT);
129            }
130        });
131    }
132
133    private void showDialog(String actionText) {
134        submitButton.setText(actionText);
135        selectLabelDialog.setText(actionText);
136        selectLabelDialog.center();
137    }
138
139    private void populateLabelList(String[] labels) {
140        labelList.clear();
141        for (String label : labels) {
142            labelList.addItem(label);
143        }
144    }
145
146    public void onClick(ClickEvent event) {
147        selectLabelDialog.hide();
148
149        if (event.getSource() == cancelButton) {
150            return;
151        }
152
153        if (submitButton.getText().equals(ADD_TEXT)) {
154            SimpleCallback doAdd = new SimpleCallback() {
155                public void doCallback(Object source) {
156                    addOrRemoveLabel((String) source, true);
157                }
158            };
159
160            if (stack.getSelectedIndex() == STACK_CREATE) {
161                addLabel(newLabelName.getText(), doAdd);
162            } else {
163                doAdd.doCallback(getSelectedLabel());
164            }
165        } else {
166            assert (submitButton.getText().equals(REMOVE_TEXT));
167            addOrRemoveLabel(getSelectedLabel(), false);
168        }
169    }
170
171    private String getSelectedLabel() {
172        return labelList.getItemText(labelList.getSelectedIndex());
173    }
174
175    private void addLabel(final String name, final SimpleCallback onFinished) {
176        JSONObject args = new JSONObject();
177        args.put("name", new JSONString(name));
178        rpcProxy.rpcCall("add_test_label", args, new JsonRpcCallback() {
179            @Override
180            public void onSuccess(JSONValue result) {
181                onFinished.doCallback(name);
182            }
183        });
184        updateLabels();
185    }
186
187    private void addOrRemoveLabel(String label, boolean add) {
188        String rpcMethod;
189        if (add) {
190            rpcMethod = "test_label_add_tests";
191        } else {
192            rpcMethod = "test_label_remove_tests";
193        }
194
195        JSONObject args = Utils.copyJSONObject(currentTestCondition);
196        args.put("label_id", new JSONString(label));
197        rpcProxy.rpcCall(rpcMethod, args, new JsonRpcCallback() {
198            @Override
199            public void onSuccess(JSONValue result) {
200                notifyManager.showMessage("Labels modified successfully");
201            }
202        });
203    }
204
205    private void updateLabels() {
206        rpcProxy.rpcCall("get_test_labels", null, new JsonRpcCallback() {
207            @Override
208            public void onSuccess(JSONValue result) {
209                staticData.setData("test_labels", result);
210            }
211        });
212    }
213
214    public void handleInvalidate(JSONObject condition) {
215        currentTestCondition = condition;
216        addOrRemoveLabel(INVALIDATED_LABEL, true);
217    }
218
219    public void handleRevalidate(JSONObject condition) {
220        currentTestCondition = condition;
221        addOrRemoveLabel(INVALIDATED_LABEL, false);
222    }
223}
224