import random
from hearthstone.enums import CardClass, CardType, GameTag, Race, Rarity
from ..actions import *
from ..aura import Refresh
from ..dsl import *
from ..events import *
from ..utils import custom_card


# For buffs which are removed when the card is moved to play (eg. cost buffs)
# This needs to be Summon, because of Summon from the hand
REMOVED_IN_PLAY = Summon(PLAYER, OWNER).after(Destroy(SELF))

ENEMY_CLASS = Attr(ENEMY_HERO, GameTag.CLASS)


RandomCard = lambda **kw: RandomCardPicker(**kw)
RandomCollectible = lambda **kw: RandomCardPicker(collectible=True, **kw)
RandomMinion = lambda **kw: RandomCollectible(type=CardType.MINION, **kw)
RandomBeast = lambda **kw: RandomMinion(race=Race.BEAST)
RandomMech = lambda **kw: RandomMinion(race=Race.MECHANICAL)
RandomMurloc = lambda **kw: RandomMinion(race=Race.MURLOC)
RandomSpell = lambda **kw: RandomCollectible(type=CardType.SPELL, **kw)
RandomTotem = lambda **kw: RandomCardPicker(race=Race.TOTEM)
RandomWeapon = lambda **kw: RandomCollectible(type=CardType.WEAPON, **kw)
RandomSparePart = lambda **kw: RandomCardPicker(spare_part=True, **kw)


class RandomEntourage(RandomCardPicker):
	def pick(self, source):
		self._cards = source.entourage
		return super().pick(source)


class RandomID(RandomCardPicker):
	def pick(self, source):
		self._cards = self.args
		return super().pick(source)


Freeze = lambda target: SetTag(target, (GameTag.FROZEN, ))
Stealth = lambda target: SetTag(target, (GameTag.STEALTH, ))
Unstealth = lambda target: UnsetTag(target, (GameTag.STEALTH, ))
Taunt = lambda target: SetTag(target, (GameTag.TAUNT, ))
GiveCharge = lambda target: SetTag(target, (GameTag.CHARGE, ))
GiveDivineShield = lambda target: SetTag(target, (GameTag.DIVINE_SHIELD, ))
GiveWindfury = lambda target: SetTag(target, (GameTag.WINDFURY, ))


CLEAVE = Hit(TARGET_ADJACENT, ATK(SELF))
COINFLIP = RandomNumber(0, 1) == 1
EMPTY_BOARD = Count(FRIENDLY_MINIONS) == 0
EMPTY_HAND = Count(FRIENDLY_HAND) == 0
FULL_BOARD = Count(FRIENDLY_MINIONS) == 7
FULL_HAND = Count(FRIENDLY_HAND) == 10
HOLDING_DRAGON = Find(FRIENDLY_HAND + DRAGON)


class JoustHelper(Evaluator):
	"""
	A helper evaluator class for jousts to allow JOUST & ... syntax.
	"""
	def __init__(self, challenger, defender):
		self.challenger = challenger
		self.defender = defender
		super().__init__()

	def trigger(self, source):
		action = Joust(self.challenger, self.defender).then(
			JoustEvaluator(Joust.CHALLENGER, Joust.DEFENDER) & self._if | self._else
		)

		return action.trigger(source)

JOUST = JoustHelper(
	RANDOM(FRIENDLY_DECK + MINION),
	RANDOM(ENEMY_DECK + MINION)
)


def SET(amt):
	return lambda self, i: amt


# Buff helper
def buff(atk=0, health=0, **kwargs):
	buff_tags = {}
	if atk:
		buff_tags[GameTag.ATK] = atk
	if health:
		buff_tags[GameTag.HEALTH] = health

	for tag in GameTag:
		if tag.name.lower() in kwargs.copy():
			buff_tags[tag] = kwargs.pop(tag.name.lower())

	if "immune" in kwargs:
		value = kwargs.pop("immune")
		buff_tags[GameTag.CANT_BE_DAMAGED] = value
		buff_tags[GameTag.CANT_BE_TARGETED_BY_OPPONENTS] = value

	if kwargs:
		raise NotImplementedError(kwargs)

	class Buff:
		tags = buff_tags

	return Buff

@@ -466,32 +466,36 @@
 domCard = lambda
+ *a,
  **kw: RandomCar
@@ -502,16 +502,20 @@
 dPicker(
+*a, 
 **kw)%0ARa
@@ -530,32 +530,36 @@
 ectible = lambda
+ *a,
  **kw: RandomCar
@@ -566,16 +566,20 @@
 dPicker(
+*a, 
 collecti
@@ -607,32 +607,36 @@
 mMinion = lambda
+ *a,
  **kw: RandomCol
@@ -636,32 +636,36 @@
 ndomCollectible(
+*a, 
 type=CardType.MI
@@ -688,32 +688,36 @@
 omBeast = lambda
+ *a,
  **kw: RandomMin
@@ -712,32 +712,36 @@
 w: RandomMinion(
+*a, 
 race=Race.BEAST)
@@ -752,32 +752,36 @@
 domMech = lambda
+ *a,
  **kw: RandomMin
@@ -776,32 +776,36 @@
 w: RandomMinion(
+*a, 
 race=Race.MECHAN
@@ -823,32 +823,36 @@
 mMurloc = lambda
+ *a,
  **kw: RandomMin
@@ -855,16 +855,20 @@
 mMinion(
+*a, 
 race=Rac
@@ -889,32 +889,36 @@
 omSpell = lambda
+ *a,
  **kw: RandomCol
@@ -918,32 +918,36 @@
 ndomCollectible(
+*a, 
 type=CardType.SP
@@ -969,32 +969,36 @@
 omTotem = lambda
+ *a,
  **kw: RandomCar
@@ -1005,16 +1005,20 @@
 dPicker(
+*a, 
 race=Rac
@@ -1039,32 +1039,36 @@
 mWeapon = lambda
+ *a,
  **kw: RandomCol
@@ -1076,16 +1076,20 @@
 ectible(
+*a, 
 type=Car
@@ -1132,21 +1132,16 @@
 = lambda
- **kw
 : Random
@@ -1166,22 +1166,16 @@
 art=True
-, **kw
 )%0A%0A%0Aclas

Allow passing positional arguments to RandomCardPicker and its helpers