# -*- coding:utf-8 -*-

# A simple example using the HTTP plugin that shows the retrieval of a
# single page via HTTP. 
#
# This script is automatically generated by ngrinder.
#
# @author admin
from net.grinder.script.Grinder import grinder
from net.grinder.script import Test
from net.grinder.plugin.http import HTTPRequest
from net.grinder.plugin.http import HTTPPluginControl
from HTTPClient import NVPair

from HTTPClient import Cookie, CookieModule, CookiePolicyHandler
from org.json import JSONObject
import random, datetime, os, copy, logging, time
import com.xhaus.jyson.JysonCodec as json
from java.lang import System
from java.lang import Exception

#control = HTTPPluginControl.getConnectionDefaults()
# if you don"t want that HTTPRequest follows the redirection, please modify the following option 0.
# control.followRedirects = 1
# if you want to increase the timeout, please modify the following option.
#control.timeout = 6000

tests = {}
tests1 = Test(1, "getaid")
tests2 = Test(2, "login")
tests3 = Test(3, "createaccount")
tests4 = Test(4, "createcharacter")

tests5 = Test(5, "armor_levelup")
tests6 = Test(6, "armor_gradeup")
tests7 = Test(7, "armor_tireup")
tests8 = Test(8, "weapon_levelup")

tests9 = Test(9, "mission_modeinfo")
tests10 = Test(10, "mission_stageinfo")
tests11 = Test(11, "mission_start")
tests12 = Test(12, "mission_result")
tests13 = Test(13, "mission_result_sweep")

tests27 = Test(27, "test_itemmake")
tests28 = Test(28, "test_addexp")

# Make any method call on req increase TPS
urlbase = "http://14.63.226.42:11000/"

class TestRunner:
    account = None
    username = "bot_test_" + str(random.randint(10000, 20000))
    req = None # req = HTTPRequest()
    aid = None
    cid = None
    level = None
    acciteminven = None
    chariteminven = None
    activesoulinven = None
    passivesoulinven = None
    reterror = None
    testlist = []

    def GET(self, url, params = {}):
        global urlbase
        pairs = []
        for k, v in params.iteritems():
            pairs.append(NVPair(k, str(v)))

        pairs.append(NVPair("Debug", str("1")))
        # set cookie before REQUEST if we have
        #if self.cookies:
        #    for cookie in self.cookies:
        #        CookieModule.addCookie(cookie, HTTPPluginControl.getThreadHTTPClientContext())

        try:
            result = self.req.GET(urlbase + url, pairs)
        except Exception, e:
            grinder.logger.error("request Exception : " + e.strerror)
            raise e
        # set cookie after REQUEST if we had not
        #if not self.cookies and result.getStatusCode() == 200:
        #    self.cookies = CookieModule.listAllCookies(HTTPPluginControl.getThreadHTTPClientContext())

        return result

    def expect(self, substring, response, code=None):   
        assert response.getStatusCode() == 200, "response.getStatusCode(): " + repr(response.getStatusCode())
        try:
            js = json.loads(response.getText())
        except Exception, e:
            grinder.logger.error("response.text: " + str(response.text))
            raise e

        #if code and len(code) > 0:
        #   assert code in js["code"], pretty(js)
        #elif substring and len(substring) > 0:
        if substring and len(substring) > 0:
            grinder.logger.debug("EXPECTS SUBSTR: " + substring + "...")
        #    assert substring in js["message"], pretty(js)
        return js

    # initlialize a thread 
    def __init__(self):
        control = HTTPPluginControl.getConnectionDefaults() 
        control.timeout = 6000
        #grinder.logger.debug("%d %d / %d %d %d" % (self.totalProcessCount, self.totalThreadCount, grinder.agentNumber, grinder.processNumber, grinder.threadNumber))
        try:
            getparams = System.getProperty("param", "1");
            self.testlist = map(int, getparams.encode('utf-8').split(","))
            grinder.logger.info("testlist : " + str(self.testlist))
        except Exception, e:
            self.testlist.append(1)
            raise e
        grinder.statistics.delayReports=True
        pass
        #self.testlist.append(3)
        #self.user_login()

    def __del__(self):
        self.user_logout()

    # test method        
    def __call__(self):
       #totalThreadCount = grinder.getProperties().getInt("grinder.threads", 1);
       #self.aid = grinder.threadNumber + 1;
       #self.aid = random.randrange(2,6) # first eqaul or over, sencond under
       #self.aid = 5
        totalProcessCount = grinder.getProperties().getInt("grinder.processes", 1);
        totalThreadCount = grinder.getProperties().getInt("grinder.threads", 1);               
        self.username = "bot_%d_%08d" % (time.time(), (grinder.agentNumber * totalProcessCount * totalThreadCount) + (grinder.processNumber * totalThreadCount) + grinder.threadNumber)
        js = None;
        trycount = 0;
        while(js == None and trycount < 10):
            try:
                js = self.user_getaid();
            except Exception, e:
                trycount = trycount + 1;
                raise e;

        if js == None:
            grinder.logger.error("request error")
            grinder.statistics.forLastTest.success = 0;
        else:
            self.user_login()
            if self.reterror == 40 or self.reterror == 1012:
                if self.reterror == 40:
                    self.creat_account()                
                    if self.reterror == 0:
                        self.create_character()
                elif self.reterror == 1012:
                    self.create_character()

                grinder.logger.info("create_character reterror : %d" % (self.reterror))
                grinder.logger.info("testlist case : " + str(self.testlist))

                if self.reterror == 0:
                    for testcase in self.testlist:
                        self.test_itemmake(testcase)
                        self.test_addexp()

                if self.reterror == 0:
                    self.user_login()
                    grinder.sleep(1000)

            for testcase in self.testlist:
                if testcase == 1:
                    self.armor_test()
                    self.mission_test()
                if testcase == 2:
                    self.weapon_test()
                    self.overlord_test()
                if testcase == 3:
                    self.shop_test()
                    self.goldexpedition_test()
                if testcase == 4:
                    self.item_sell_test()
                    self.gacha_test()

        return None

        #rnd = random.random()
        #if rnd < 0.3: js = self.building_get()
        #else: js = self.officer_list()

        #if js:
        #    grinder.statistics.forLastTest.success = 1
        #else:
        #    grinder.statistics.forLastTest.success = 0

    def test_itemmake(self, test_case=1):
        global tests, tests1, tests2, tests3, tests4, tests5, tests6, tests7, tests8, tests9, tests10, tests11, tests12, tests13
        self.req = HTTPRequest()
        tests27.record(self.req)

        if self.aid == None or self.aid == 0:
            return None
        if self.cid == None or self.cid == 0:
            return None

        makelist = []
        grinder.logger.info("test_itemmake test_case : %d" % (test_case))

        makelist.append({'itemid':303000001, 'makecount':1000000, 'makegrade':1})
        makelist.append({'itemid':303010001, 'makecount':128, 'makegrade':1})
        makelist.append({'itemid':303010102, 'makecount':80, 'makegrade':1})
        makelist.append({'itemid':303000002, 'makecount':300, 'makegrade':1})

        js = None

        for makeitem in makelist:
            grinder.sleep(200)
            e = {'op': 'makeitem'}
            e['aid'] = self.aid
            e['cid'] = self.cid
            e['itemid'] = makeitem['itemid']
            e['makecount'] = makeitem['makecount']
            e['makegrade'] = makeitem['makegrade']
            r = self.GET('RequestItem.aspx', e)        
            js = self.expect(None, r)
            self.reterror = js['resultcode'];
            if self.reterror != 0:
                grinder.logger.info("test_itemmake reterror : %d" % (self.reterror))
                grinder.logger.error("request error")
                grinder.statistics.forLastTest.success = 0;
            else:
                grinder.statistics.forLastTest.success = 1
        return js

    def test_addexp(self, test_case=1):
        global tests, tests1, tests2, tests3, tests4, tests5, tests6, tests7, tests8, tests9, tests10, tests11, tests12, tests13
        self.req = HTTPRequest()
        tests28.record(self.req)

        if self.aid == None or self.aid == 0:
            return None
        if self.cid == None or self.cid == 0:
            return None

        e = {"op": "getexp"}
        e["aid"] = self.aid
        e["cid"] = self.cid
        e["exp"] = 123680   # for 40level set
        r = self.GET("RequestAccount.aspx", e)        
        js = self.expect(None, r)
        self.reterror = js["resultcode"];
        if self.reterror != 0:
            grinder.logger.info("test_addexp reterror : %d" % (self.reterror))
            grinder.logger.error("request error")
            grinder.statistics.forLastTest.success = 0;
        else:
            grinder.statistics.forLastTest.success = 1
            self.level = 41;
        return js

    def user_logout(self):
        grinder.logger.info("logged out : %d" % (self.aid))

    def user_getaid(self):
        global tests, tests1, tests2, tests3, tests4, tests5, tests6, tests7, tests8, tests9, tests10, tests11, tests12, tests13
        grinder.sleep(random.randrange(300,1000))

        self.req = HTTPRequest()
        tests1.record(self.req)
        e = {"op": "get_user_aid"}
        e["platform_type"] = 10000
        e["user_id"] = self.username
        r = self.GET("RequestPrivateServer.aspx", e)        
        js = self.expect(None, r)
        self.reterror = js["resultcode"];

        if self.reterror == 0:
            self.aid = js["aid"]
            grinder.statistics.forLastTest.success = 1
        else:
            grinder.logger.info("getaid reterror : %d" % (self.reterror))
            grinder.logger.error("request error")
            grinder.statistics.forLastTest.success = 0;
        return js;

    def user_login(self):
        global tests, tests1, tests2, tests3, tests4, tests5, tests6, tests7, tests8, tests9, tests10, tests11, tests12, tests13
        self.req = HTTPRequest()
        tests2.record(self.req)

        if self.aid == None or self.aid == 0:
            return None
            
        e = {"op": "login"}
        e["aid"] = self.aid;
        #e = {"username": self.username, "password": self.password}
        #e["country"] = 1 if self.allies else 2
        #e["market_type"] = self.market_type
        #e["ssl"] = True
        #e["email"] = self.username + "@test.ee.com"

        r = self.GET("RequestAccount.aspx", e)        
        js = self.expect(None, r)
        self.reterror = js["resultcode"];

        grinder.logger.info("logged reterror : %d" % (self.reterror))

        if self.reterror == 0:
            self.account = js["account"]
            self.aid = self.account["aid"]
            self.cid = js["charactergroup"][0]
            self.level = js["characterlist"][0]["level"]
            self.acciteminven = js["accountinven"]
            self.chariteminven = js["characterinven"]
            #soullist = self.expect(None, js["soul_list"])
            for charsoul in js["soul_list"]:
                if charsoul["cid"] == self.cid:   
                    self.activesoulinven = charsoul["active_soul_list"]
                    self.passivesoulinven = charsoul["passive_soul_list"]
                    break
            grinder.logger.info("user_login in aid : %d" % (self.aid))
            grinder.logger.info("user_login in cid : %d" % (self.cid))
            #grinder.logger.info("user_login in characterinven : " + str(self.chariteminven))
            #grinder.logger.info("user_login in activesoulinven : " + str(self.activesoulinven))
            #grinder.logger.info("user_login in passivesoulinven : " + str(self.passivesoulinven))
        elif self.reterror > 1900:
            grinder.logger.info("user_login reterror : %d" % (self.reterror))

        grinder.statistics.forLastTest.success = 1
        return js

    def creat_account(self):
        global tests, tests1, tests2, tests3, tests4, tests5, tests6, tests7, tests8, tests9, tests10, tests11, tests12, tests13
        self.req = HTTPRequest()
        tests3.record(self.req)

        if self.aid == None or self.aid == 0:
            return None
        e = {"op": "createaccount"}
        e["aid"] = self.aid;        
        e["userid"] = self.username;
        e["username"] = self.username;        
        e["CountryCode"] = "kr";
        e["languagecode"] = 0;

        r = self.GET("RequestAccount.aspx", e)        
        js = self.expect(None, r)
        self.reterror = js["resultcode"];
        if self.reterror > 1900:
            grinder.logger.info("creat_account reterror : %d" % (self.reterror))
            grinder.logger.error("request error")
            grinder.statistics.forLastTest.success = 0;
        else:
            grinder.statistics.forLastTest.success = 1
        return js


    def create_character(self):
        global tests, tests1, tests2, tests3, tests4, tests5, tests6, tests7, tests8, tests9, tests10, tests11, tests12, tests13
        self.req = HTTPRequest()
        tests4.record(self.req)

        if self.aid == None or self.aid == 0:
            return None
        e = {"op": "createcharacter"}
        e["aid"] = self.aid;
        e["class"] = random.randrange(1,3)

        r = self.GET("RequestAccount.aspx", e)        
        js = self.expect(None, r)
        self.reterror = js["resultcode"];
        self.cid = js["cid"];

        if self.reterror > 1900:
            grinder.logger.info("createcharacter reterror : %d" % (self.reterror))
            grinder.logger.error("request error")
            grinder.statistics.forLastTest.success = 0;
        else:
            grinder.statistics.forLastTest.success = 1
        return js

    def armor_test(self):
        grinder.logger.info("armor_test start")

        armoritemlist = []
        for charitem in self.chariteminven:
            if charitem["equipposition"].find("Head") > 0:
                armoritemlist.append(charitem)
            elif charitem["equipposition"].find("Body")  > 0:
                armoritemlist.append(charitem)
            elif charitem["equipposition"].find("Hand")  > 0:
                armoritemlist.append(charitem)
            elif charitem["equipposition"].find("Foot") > 0:
                armoritemlist.append(charitem)

        for charitem in armoritemlist:
            for i in range(0,5):
                grinder.sleep(500)
                self.armor_levelup(charitem["invenseq"])
                if i < 4:
                    grinder.sleep(1000)
                    self.armor_gradeup(charitem["invenseq"])
                else:
                    grinder.sleep(1000)
                    self.armor_tireup(charitem["invenseq"])        
        return None


    def armor_levelup(self, invenseq, try_count = 5):
        global tests, tests1, tests2, tests3, tests4, tests5, tests6, tests7, tests8, tests9, tests10, tests11, tests12, tests13
        self.req = HTTPRequest()
        tests5.record(self.req)

        grinder.logger.info("armor_levelup invenseq : %d" % (invenseq))

        if self.aid == None or self.aid == 0:
            return None
        e = {"op": "enchantarmor"}
        e["aid"] = self.aid;
        e["cid"] = self.cid;
        e["itemseq"] = invenseq;
        e["try_count"] = try_count;

        r = self.GET("RequestItem.aspx", e)        
        js = self.expect(None, r)
        self.reterror = js["resultcode"];

        if self.reterror > 1900:
            grinder.logger.info("armor_levelup reterror : %d" % (self.reterror))
            grinder.logger.error("request error")
            grinder.statistics.forLastTest.success = 0;
        else:
            grinder.statistics.forLastTest.success = 1
        return js        

    def armor_gradeup(self, invenseq, try_count = 5):
        global tests, tests1, tests2, tests3, tests4, tests5, tests6, tests7, tests8, tests9, tests10, tests11, tests12, tests13
        self.req = HTTPRequest()
        tests6.record(self.req)

        grinder.logger.info("armor_gradeup invenseq : %d" % (invenseq))

        if self.aid == None or self.aid == 0:
            return None
        e = {"op": "evolutionarmor"}
        e["aid"] = self.aid;
        e["cid"] = self.cid;
        e["itemseq"] = invenseq;

        r = self.GET("RequestItem.aspx", e)        
        js = self.expect(None, r)
        self.reterror = js["resultcode"];

        if self.reterror > 1900:
            grinder.logger.info("armor_gradeup reterror : %d" % (self.reterror))
            grinder.logger.error("request error")
            grinder.statistics.forLastTest.success = 0;
        else:
            grinder.statistics.forLastTest.success = 1
        return js        

    def armor_tireup(self, invenseq, try_count = 5):
        global tests, tests1, tests2, tests3, tests4, tests5, tests6, tests7, tests8, tests9, tests10, tests11, tests12, tests13
        self.req = HTTPRequest()
        tests7.record(self.req)

        grinder.logger.info("armor_tireup invenseq : %d" % (invenseq))

        if self.aid == None or self.aid == 0:
            return None
        e = {"op": "metalworkarmor"}
        e["aid"] = self.aid;
        e["cid"] = self.cid;
        e["itemseq"] = invenseq;

        r = self.GET("RequestItem.aspx", e)        
        js = self.expect(None, r)
        self.reterror = js["resultcode"];

        if self.reterror > 1900:
            grinder.logger.info("armor_tireup reterror : %d" % (self.reterror))
            grinder.logger.error("request error")
            grinder.statistics.forLastTest.success = 0;
        else:
            grinder.statistics.forLastTest.success = 1
        return js


    def mission_test(self):
        grinder.logger.info("mission_test start")

        for i in range(1,11):
            grinder.sleep(2000)
            self.mission_start(i)
            grinder.sleep(15000)
            self.mission_result(i,1,0)

        for i in range(1,11):
            for j in range(0,4):
                grinder.sleep(2000)
                self.mission_result(i, 1, 1)
        return None

    def mission_info(self, stageid, worldid = 1):
        global tests, tests1, tests2, tests3, tests4, tests5, tests6, tests7, tests8, tests9, tests10, tests11, tests12, tests13
        self.req = HTTPRequest()
        tests10.record(self.req)
        grinder.sleep(1000)

        grinder.logger.info("mission_stage_info : %d-%d" % (worldid, stageid))

        if self.aid == None or self.aid == 0 or stageid == 0:
            return None

        e = {"op": "mission_taskinfo"}
        e["aid"] = self.aid;
        e["cid"] = self.cid;
        e["worldid"] = worldid;
        e["stageid"] = stageid;

        r = self.GET("RequestMission.aspx", e)        
        js = self.expect(None, r)
        self.reterror = js["resultcode"];

        if self.reterror > 1900:
            grinder.logger.info("mission_stage_info reterror : %d" % (self.reterror))
            grinder.logger.error("request error")
            grinder.statistics.forLastTest.success = 0;
        else:
            grinder.statistics.forLastTest.success = 1
        return js


    def mission_start(self, stageid, worldid = 1):
        global tests, tests1, tests2, tests3, tests4, tests5, tests6, tests7, tests8, tests9, tests10, tests11, tests12, tests13

        self.mission_info(stageid, worldid)

        self.req = HTTPRequest()
        tests11.record(self.req)

        grinder.logger.info("mission_start : %d-%d" % (worldid, stageid))

        if self.aid == None or self.aid == 0 or stageid == 0:
            return None

        e = {"op": "mission_start"}
        e["aid"] = self.aid;
        e["cid"] = self.cid;
        e["worldid"] = worldid;
        e["stageid"] = stageid;

        r = self.GET("RequestMission.aspx", e)        
        js = self.expect(None, r)
        self.reterror = js["resultcode"];

        if self.reterror > 1900:
            grinder.logger.info("mission_start reterror : %d" % (self.reterror))
            grinder.logger.error("request error")
            grinder.statistics.forLastTest.success = 0;
        else:
            grinder.statistics.forLastTest.success = 1
        return js


    def mission_result(self, stageid, worldid = 1, sweep = 0):
        global tests, tests1, tests2, tests3, tests4, tests5, tests6, tests7, tests8, tests9, tests10, tests11, tests12, tests13

        self.mission_info(stageid, worldid)
        self.req = HTTPRequest()

        if sweep == 0:
            tests12.record(self.req)
            grinder.logger.info("mission_result : %d-%d" % (worldid, stageid))
        else:
            tests13.record(self.req)
            grinder.logger.info("mission_result_sweep : %d-%d" % (worldid, stageid))

        if self.aid == None or self.aid == 0 or stageid == 0:
            return None

        e = {}
        if sweep == 0:
            e["op"] = "mission_result";
        else:
            e["op"] = "mission_result_sweep";

        e["aid"] = self.aid;
        e["cid"] = self.cid;
        e["worldid"] = worldid;
        e["stageid"] = stageid;
        e["cleartime"] = 15;
        e["clear"] = 1;

        r = self.GET("RequestMission.aspx", e)        
        js = self.expect(None, r)
        self.reterror = js["resultcode"];

        if self.reterror > 1900:
            if sweep == 0:
                grinder.logger.info("mission_result reterror : %d" % (self.reterror))
            else:
                grinder.logger.info("mission_result_sweep reterror : %d" % (self.reterror))
                grinder.logger.error("request error")
                grinder.statistics.forLastTest.success = 0;
        else:
            grinder.statistics.forLastTest.success = 1

        return js


    def weapon_test(self):
        grinder.logger.info("armor_test start")

        weaponitem = None
        for charitem in self.chariteminven:
            if charitem["equipposition"].find("Weapon") > 0:
                weaponitem = charitem

        if weaponitem != None:
            for i in range(0,10):
                self.weapon_levelup(weaponitem["invenseq"])

        return None


    def weapon_levelup(self, invenseq):
        global tests, tests1, tests2, tests3, tests4, tests5, tests6, tests7, tests8, tests9, tests10, tests11, tests12, tests13
        grinder.sleep(1000)

        self.req = HTTPRequest()
        tests8.record(self.req)
        grinder.logger.info("weapon_levelup invenseq : %d" % (invenseq))

        if self.aid == None or self.aid == 0:
            return None
        e = {"op": "enchantweapon"}
        e["aid"] = self.aid;
        e["cid"] = self.cid;
        e["itemseq"] = invenseq;

        r = self.GET("RequestItem.aspx", e)        
        js = self.expect(None, r)
        self.reterror = js["resultcode"];

        if self.reterror > 1900:
            grinder.logger.info("weapon_levelup reterror : %d" % (self.reterror))
            grinder.logger.error("request error")
            grinder.statistics.forLastTest.success = 0;
        else:
            grinder.statistics.forLastTest.success = 1
        return js