package test.gigaspaces;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Random;

import org.testng.Assert;
import org.testng.ITestResult;
import org.testng.TestListenerAdapter;
import org.testng.TestNG;
import org.testng.annotations.Configuration;
import org.testng.annotations.Test;
import org.testng.remote.SuiteDispatcher;
import org.testng.xml.XmlClass;
import org.testng.xml.XmlSuite;
import org.testng.xml.XmlTest;

import test.BaseDistributedTest;

import testhelper.OutputDirectoryPatch;

public class DistributedTest extends BaseDistributedTest {
  
  private List<Thread> m_hostThreads = new ArrayList<Thread>();

  protected Thread startSlave(final String filename) {
    Thread result = new Thread(new Runnable() {
      public void run() {
        TestNG.main(new String[] { "-slave", filename, "-d", OutputDirectoryPatch.getOutputDirectory() });       
      }
    });
    result.setName("Slave-" + filename);
    result.start();
    m_hostThreads.add(result);
    return result;
  }
  
  private File createMasterProperties(String strategy)
  throws IOException 
  {
    String fileName = "remote";
    
    File result = File.createTempFile(fileName, ".properties");
    result.deleteOnExit();
    Properties p = new Properties();
    p.setProperty("testng.master.strategy", strategy);
    p.setProperty("testng.verbose", "0");
    p.setProperty("testng.master.adpter", "org.testng.gigaspaces.SpaceMasterAdapter");
    p.setProperty("gigaspaces.url", "/./TestNGSpace?groups=TestNG");
    FileOutputStream fos = new FileOutputStream(result);
    p.store(fos, "Automatically generated by tests");
    fos.close();    
    
    return result;
  }
  
  private File createSlaveProperties()
  throws IOException 
  {
    String fileName = "remote";
    
    File result = File.createTempFile(fileName, ".properties");
    result.deleteOnExit();
    Properties p = new Properties();
    p.setProperty("testng.verbose", "0");
    p.setProperty("testng.slave.adpter", "org.testng.gigaspaces.SpaceWorkerAdapter");
    p.setProperty("gigaspaces.url", "jini://*/*/TestNGSpace?groups=TestNG&timeout=10000");
    FileOutputStream fos = new FileOutputStream(result);
    p.store(fos, "Automatically generated by tests");
    fos.close();    
    
    return result;
  }
  
  private XmlSuite createSuite(String name, Class[] classes) {
    XmlSuite result = new XmlSuite();
    result.setName(name);
    
    for (Class c : classes) {
      XmlTest test1 = new XmlTest(result);
      test1.setName(c.getName());
      XmlClass class1 = new XmlClass(c);
      test1.getXmlClasses().add(class1);
    }
    
    return result;
  }
  
//  @ Configuration(beforeTestClass = true) 
  private void startSlaves() throws IOException{
	  int port = new Random().nextInt(50000) + 2000;
	  m_ports = new String[] { Integer.toString(port), Integer.toString(port+1)};

	  File slaveFile = createSlaveProperties();
	  startSlave( slaveFile.getCanonicalPath());
	  
	  slaveFile = createSlaveProperties();
	  startSlave( slaveFile.getCanonicalPath());
  }

  private String[] m_ports = new String[2];

  public TestListenerAdapter twoHosts(String strategy) throws IOException {  
    TestNG tng = new TestNG();
    tng.setOutputDirectory(OutputDirectoryPatch.getOutputDirectory());
    
    File masterFile = createMasterProperties(strategy);
    tng.setMaster(masterFile.getAbsolutePath());
    
    XmlSuite suite = createSuite("DistributedSuite1", new Class[] { Test1.class, Test2.class });
    tng.setXmlSuites(Arrays.asList(new XmlSuite[] { suite }));
    
    TestListenerAdapter result = new TestListenerAdapter();
    tng.addListener(result);
    tng.run();
    
    String[] passed = {
        "f1", "f2"
    };
    String[] failed = {};
    String[] skipped = {};

    verifyTests("Passed", passed, toMap(result.getPassedTests()));
    verifyTests("Failed", failed, toMap(result.getFailedTests()));
    verifyTests("Skipped", skipped, toMap(result.getSkippedTests()));
    
    return result;
  }
  
  @Test
  public void twoHostsWithTestStrategy() throws IOException {
    startSlaves();
    TestListenerAdapter listener = twoHosts(SuiteDispatcher.STRATEGY_TEST);
    
    boolean found1 = false;
    boolean found2 = false;
    for (ITestResult tr : listener.getPassedTests()) {
      String host = tr.getHost();
      if (! found1) found1 = host.contains(m_ports[0]);
      if (! found2) found2 = host.contains(m_ports[1]);
    }
    Assert.assertTrue(found1, "No tests ran on port " + m_ports[0]);
    Assert.assertTrue(found2, "No tests ran on port " + m_ports[1]);    
  }
  
  @Test
  public void twoHostsWithSuiteStrategy() throws IOException {
    startSlaves();
    TestListenerAdapter listener = twoHosts( SuiteDispatcher.STRATEGY_SUITE);
  }

  private Map<String, ITestResult> toMap(List<ITestResult> results) {
    Map<String, ITestResult> result = new HashMap<String, ITestResult>();
    for (ITestResult tr : results) {
      result.put(tr.getName(), tr);
    }
    
    return result;
  }
  private void ppp(String string) {
    System.out.println("[DistributedTest] " + string);
  }
}

