/*
 * Copyright 2015 www.seleniumtests.com
 * Licensed 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 com.seleniumtests.core;

import java.io.IOException;

import java.lang.reflect.Method;

import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;

import org.testng.ITestContext;

import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.BeforeTest;

import org.testng.xml.XmlTest;

import com.seleniumtests.driver.WebUIDriver;

/**
 * This class initializes context, sets up and tears down and clean up drivers An STF test should extend this class.
 */
public abstract class SeleniumTestPlan {
    private static final Logger logger = TestLogging.getLogger(SeleniumTestPlan.class);
    private Date start;

    /**
     * @param   testContext
     *
     * @throws  IOException
     */
    @BeforeSuite(alwaysRun = true)
    public void beforeTestSuite(final ITestContext testContext) throws IOException {
        System.out.println("####################################################");
        System.out.println("####################################################");
        System.out.println("####################################################");
        System.out.println("WWW.SELENIUMTESTS.COM");
        System.out.println("WWW.SELENIUMTESTS.COM");
        System.out.println("WWW.SELENIUMTESTS.COM");
        System.out.println("####################################################");
        System.out.println("####################################################");
        System.out.println("####################################################");
        start = new Date();
        SeleniumTestsContextManager.initGlobalContext(testContext);
        SeleniumTestsContextManager.initThreadContext(testContext, null);
    }

    /**
     * Configure Test Params setting.
     *
     * @param  xmlTest
     */
    @BeforeTest(alwaysRun = true)
    public void beforeTest(final ITestContext testContext, final XmlTest xmlTest) {
        SeleniumTestsContextManager.initTestLevelContext(testContext, xmlTest);
    }

    @BeforeMethod(alwaysRun = true)
    public void beforeTestMethod(final Object[] parameters, final Method method, final ITestContext testContex,
            final XmlTest xmlTest) {
        logger.info(Thread.currentThread() + " Start method " + method.getName());
        SeleniumTestsContextManager.initThreadContext(testContex, xmlTest);
        if (method != null) {
            SeleniumTestsContextManager.getThreadContext().setAttribute(SeleniumTestsContext.TEST_METHOD_SIGNATURE,
                buildMethodSignature(method, parameters));
        }
    }

    @AfterSuite(alwaysRun = true)
    public void afterTestSuite() {
        logger.info("Test Suite Execution Time: " + (new Date().getTime() - start.getTime()) / 1000 / 60 + " minutes.");
    }

    /**
     * clean up.
     *
     * @param  parameters
     * @param  method
     * @param  testContex
     * @param  xmlTest
     */
    @AfterMethod(alwaysRun = true)
    public void afterTestMethod(final Object[] parameters, final Method method, final ITestContext testContex,
            final XmlTest xmlTest) {
        List<TearDownService> serviceList = SeleniumTestsContextManager.getThreadContext().getTearDownServices();
        if (serviceList != null && !serviceList.isEmpty()) {
            for (TearDownService service : serviceList) {
                service.tearDown();
            }
        }

        WebUIDriver.cleanUp();
        logger.info(Thread.currentThread() + " Finish method " + method.getName());
        TestRetryAnalyzer.resetCount();
    }

    private String buildMethodSignature(final Method method, final Object[] parameters) {
        return method.getDeclaringClass().getCanonicalName() + "." + method.getName() + "("
                + buildParameterString(parameters) + ")";
    }

    /**
     * Remove name space from parameters.
     *
     * @param   parameters
     *
     * @return
     */
    private String buildParameterString(final Object[] parameters) {
        StringBuffer parameter = new StringBuffer();

        if (parameters != null) {
            for (int i = 0; i < parameters.length; i++) {
                if (parameters[i] == null) {
                    parameter.append("null, ");
                } else if (parameters[i] instanceof java.lang.String) {
                    parameter.append("\"").append(parameters[i]).append("\", ");
                } else {
                    parameter.append(parameters[i]).append(", ");
                }
            }
        }

        if (parameter.length() > 0) {
            parameter.delete(parameter.length() - 2, parameter.length() - 1);
        }

        return parameter.toString();
    }
}

@@ -630,110 +630,45 @@
 ort 
-java.io.IOException;%0A%0Aimport java.lang.reflect.Method;%0A%0Aimport java.util.Date;%0Aimport java.util.List;%0A
+com.seleniumtests.driver.WebUIDriver;
 %0Aimp
@@ -696,17 +696,16 @@
 Logger;%0A
-%0A
 import o
@@ -728,17 +728,16 @@
 ontext;%0A
-%0A
 import o
@@ -758,27 +758,17 @@
 tations.
-AfterMethod
+*
 ;%0Aimport
@@ -783,237 +783,127 @@
 tng.
-annotations.AfterSuite;%0Aimport org.testng.annotations.BeforeMethod;%0Aimport org.testng.annotations.BeforeSuite;%0Aimport org.testng.annotations.BeforeTest;%0A%0Aimport org.testng.xml.XmlTest;%0A%0Aimport com.seleniumtests.driver.WebUIDriver
+xml.XmlTest;%0A%0Aimport java.io.IOException;%0Aimport java.lang.reflect.Method;%0Aimport java.util.Date;%0Aimport java.util.List
 ;%0A%0A/
@@ -3599,16 +3599,22 @@
         
+final 
 List%3CTea
@@ -3789,16 +3789,22 @@
    for (
+final 
 TearDown
@@ -4016,48 +4016,8 @@
 ));%0A
-        TestRetryAnalyzer.resetCount();%0A
     
@@ -4457,16 +4457,22 @@
         
+final 
 StringBu

declare local variable as final