/**************************************************************
 *
 * 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 pvt.gui;

import static org.junit.Assert.*;
import static org.openoffice.test.common.Testspace.*;
import static org.openoffice.test.vcl.Tester.*;
import static testlib.gui.AppTool.*;
import static testlib.gui.UIMap.*;

import java.awt.Rectangle;
import java.util.HashMap;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;
import org.openoffice.test.OpenOffice;
import org.openoffice.test.common.Condition;
import org.openoffice.test.common.DataSheet;
import org.openoffice.test.common.GraphicsUtil;
import org.openoffice.test.common.Logger;


public class Benchmark {
	@Rule
	public Logger log = Logger.getLogger(this);

	@Rule
	public TestName testname = new TestName();

	private static DataSheet result;

	private static final double INTERVAL = 0.1;

	private static int repeat = 2;

	private int i  = 0;

	public Benchmark() {

	}

	@BeforeClass
	public static void beforeClass() throws Exception {
		OpenOffice.killAll();
		result = new DataSheet(getFile("output/" + Benchmark.class.getName() + ".xml"));
		result.addRow("data", "Scenario", "No", "Consumed Time", "Memory(VSZ)", "Memory(RSS)", "Handles(Windows Only)");
	}

	@AfterClass
	public static void afterClass() throws Exception {
		//app.stop();
	}

	@Before
	public void before() {
		app.start(true);
		app.quit();
	}

	@After
	public void after() {
		if (i < repeat)
			result.addRow("data", testname.getMethodName(), i, "err", "err", "err", "err", "err");
	}

	private void addRecord(long start, long end) {
		sleep(2);
		HashMap<String, Object>  perf = aoo.getPerfData();
		result.addRow("data", testname.getMethodName(), i, (end - start), perf.get("vsz"), perf.get("rss"), perf.get("handles"));
	}

	@Test
	public void coolStartup() throws Exception {
		for (i = 0; i < repeat; i++) {
			aoo.cleanUserInstallation();
			assertFalse("User profile exists", aoo.getUserInstallation().exists());
			aoo.start();
			long start = System.currentTimeMillis();
			startcenter.waitForExistence(120, INTERVAL);
			long end = System.currentTimeMillis();
			addRecord(start, end);
			app.quit();
		}

	}

	@Test
	public void warmStartup() throws Exception {
		for (i = 0; i < repeat; i++) {
			assertTrue("User profile exists", aoo.getUserInstallation().exists());
			aoo.start();
			long start = System.currentTimeMillis();
			startcenter.waitForExistence(120, INTERVAL);
			long end = System.currentTimeMillis();
			addRecord(start, end);
			app.quit();
		}

	}

	@Test
	public void newTextDocument() {
		for (i = 0; i < repeat; i++) {
			app.start();
			startCenterWriterButton.click(0.5, 0.5);
			long start = System.currentTimeMillis();
			writer.waitForExistence(60, INTERVAL);
			long end = System.currentTimeMillis();
			addRecord(start, end);
			app.quit();
		}

	}

	@Test
	public void newSpreadsheet() {
		for (i = 0; i < repeat; i++) {
			app.start();
			startCenterCalcButton.click(0.5, 0.5);
			long start = System.currentTimeMillis();
			calc.waitForExistence(60, INTERVAL);
			long end = System.currentTimeMillis();
			addRecord(start, end);
			app.quit();
		}

	}

	@Test
	public void newPresentation() {
		for (i = 0; i < repeat; i++) {
			app.start();
			startCenterImpressButton.click(0.5, 0.5);
			presentationWizard.click(0.9, 0.95);
			long start = System.currentTimeMillis();
			impress.waitForExistence(60, INTERVAL);
			long end = System.currentTimeMillis();
			addRecord(start, end);
			app.quit();
		}

	}

	@Test
	public void slideShow() {
		String path = prepareData("pvt/slideshow.odp");
		final Rectangle rect = GraphicsUtil.getScreenRectangle();
		// when slide show is running, top-center area will be filled with green
		rect.setRect(rect.getCenterX(), 2, 2, 2);
		for (i = 0; i < repeat; i++) {
			app.start();
			open(path);
			impress.waitForExistence(60, 1);
			sleep(2);
			assertFalse("Slideshow control exists", slideShow.exists());
			assertFalse("Slideshow is not started", GraphicsUtil.isFilledWith(0xFF00FF00, rect));
			typeKeys("<F5>");
			long start = System.currentTimeMillis();
			new Condition() {
				@Override
				public boolean value() {
					return GraphicsUtil.isFilledWith(0xFF00FF00, rect);
				}

			}.waitForTrue("", 120, INTERVAL);
			long end = System.currentTimeMillis();
			addRecord(start, end);
			slideShow.typeKeys("<esc>");
			sleep(2);
			app.quit();
		}

	}

	@Test
	public void loadFinishPlainODT() {
		loadFinish("pvt/plain_200p.odt", "Page 1 / 23[0-9]{1}");
	}

	@Test
	public void loadFinishPlainDOC() {
		loadFinish("pvt/plain_50p.doc", "Page i / 5[0-9]{1}");
	}

	@Test
	public void loadFinishPlainDOCX() {
		loadFinish("pvt/plain_200p.docx", "Page 1 / 1[8-9]{1}[0-9]{1}");
	}

	@Test
	public void loadFinishPlainODS() {
		loadFinish("pvt/plain_11s.ods", "Sheet 1 / 11");
	}

	@Test
	public void loadFinishPlainXLS() {
		loadFinish("pvt/plain_11s.xls", "Sheet 1 / 11");
	}

	@Test
	public void loadFinishPlainXLSX() {
		loadFinish("pvt/plain_11s.xlsx", "Sheet 1 / 11");
	}

	@Test
	public void loadFinishPlainODP() {
		loadFinish("pvt/plain_200p.odp", "Slide 1 / 200");
	}

	@Test
	public void loadFinishPlainPPT() {
		loadFinish("pvt/plain_200p.ppt", "Slide 1 / 200");
	}

	@Test
	public void loadFinishPlainPPTX() {
		loadFinish("pvt/plain_200p.pptx", "Slide 1 / 200");
	}

	@Test
	public void loadFinishComplexDOC() {
		loadFinish("pvt/complex_300p.doc", "Page 1 / 3[0-9]{2}");
	}

	@Test
	public void loadFinishComplexDOCX() {
		loadFinish("pvt/complex_400p.docx", "Page 1 / 3[2-9]{2}");
	}

	@Test
	public void loadFinishComplexODT() {
		loadFinish("pvt/complex_800p.odt", "Page 1 / 8[0-9]{2}");
	}

	@Test
	public void loadFinishComplexODS() {
		loadFinish("pvt/complex_19s.ods", "Sheet 8 / 19");
	}

	@Test
	public void loadFinishComplexXLS() {
		loadFinish("pvt/complex_29s.xls", "Sheet 2 / 29");
	}

	@Test
	public void loadFinishComplexXLSX() {
		loadFinish("pvt/complex_29s.xlsx", "Sheet 29 / 29");
	}

	@Test
	public void loadFinishComplexODP() {
		loadFinish("pvt/complex_150p.odp", "Slide 1 / 150");
	}

	@Test
	public void loadFinishComplexPPT() {
		loadFinish("pvt/complex_100p.ppt", "Slide 1 / 100");
	}

	@Test
	public void loadFinishComplexPPTX() {
		loadFinish("pvt/complex_100p.pptx", "Slide 1 / 100");
	}

	public void loadFinish(String file, final String indicator) {
		final int openIndicatorIndex = file.matches(".*\\.(odp|ppt|pptx)$") ? 4 : 0;
		String path = prepareData(file);
		for (i = 0; i < repeat; i++) {
			app.start();
			app.dispatch(".uno:Open");
			filePickerPath.setText(path);
			sleep(1);
			filePickerOpen.click(0.5, 0.5);
			long start = System.currentTimeMillis();
			new Condition() {
				@Override
				public boolean value() {
					try {
						String text = statusBar.getItemText(openIndicatorIndex);
						return text.matches(indicator);
					} catch (Exception e) {
						return false;
					}
				}

			}.waitForTrue("", 120, INTERVAL);
			long end = System.currentTimeMillis();
			addRecord(start, end);
			discard();
			app.quit();
		}

	}

	@Test
	public void savePlainODT() {
		save("pvt/plain_200p.odt", "Page 1 / 23[0-9]{1}");
	}

	@Test
	public void savePlainDOC() {
		save("pvt/plain_50p.doc", "Page i / 5[0-9]{1}");
	}

	@Test
	public void savePlainODS() {
		save("pvt/plain_11s.ods", "Sheet 1 / 11");
	}

	@Test
	public void savePlainXLS() {
		save("pvt/plain_11s.xls", "Sheet 1 / 11");
	}

	@Test
	public void savePlainODP() {
		save("pvt/plain_200p.odp", "Slide 1 / 200");
	}

	@Test
	public void savePlainPPT() {
		save("pvt/plain_200p.ppt", "Slide 1 / 200");
	}

	@Test
	public void saveComplexODT() {
		save("pvt/complex_800p.odt", "Page 1 / 8[0-9]{2}");
	}

	@Test
	public void saveComplexDOC() {
		save("pvt/complex_300p.doc", "Page 1 / 3[0-9]{2}");
	}

	@Test
	public void saveComplexODS() {
		save("pvt/complex_19s.ods", "Sheet 8 / 19");
	}

	@Test
	public void saveComplexXLS() {
		save("pvt/complex_29s.xls", "Sheet 2 / 29");
	}

	@Test
	public void saveComplexODP() {
		save("pvt/complex_150p.odp", "Slide 1 / 150");
	}

	@Test
	public void saveComplexPPT() {
		save("pvt/complex_100p.ppt", "Slide 1 / 100");
	}

	public void save(String file, final String openIndicator) {
		boolean alienFormat = file.matches(".*\\.(doc|xls|ppt|docx|xlsx|pptx)$");
		final int openIndicatorIndex = file.matches(".*\\.(odp|ppt|pptx)$") ? 4 : 0;
		final int saveIndicatorIndex = file.matches(".*\\.(odt|doc|docx)$") ? 5 : file.matches(".*\\.(ods|xls|xlsx)$") ? 4 : 2;
		String picture = prepareData("image/red_64x64.bmp");
		for (i = 0; i < repeat; i++) {
			String dir = "temp/file" + i;
			getFile(dir).mkdirs();
			app.start();
			open(prepareData(file, dir));
			new Condition() {
				@Override
				public boolean value() {
					try {
						String text = statusBar.getItemText(openIndicatorIndex);
						return text.matches(openIndicator);
					} catch (Exception e) {
						return false;
					}
				}

			}.waitForTrue("", 120, 1);
			sleep(2);
			insertPicture(picture);
			sleep(5);
			assertEquals("File is modified", "*", statusBar.getItemText(saveIndicatorIndex));
			app.dispatch(".uno:Save");
			if (alienFormat) {
				alienFormatDlg.waitForExistence(3, 1);
				sleep(1);
				typeKeys("<enter>");
			}

			long start = System.currentTimeMillis();
			new Condition() {
				@Override
				public boolean value() {
					try {
						String text = statusBar.getItemText(saveIndicatorIndex);
						return " ".equals(text);
					} catch (Exception e) {
						return false;
					}
				}

			}.waitForTrue("", 120, INTERVAL);
			long end = System.currentTimeMillis();
			addRecord(start, end);
			close();
			app.stop();
		}

	}
}
