package org.mage.test.cards.copy;

import mage.abilities.keyword.IndestructibleAbility;
import mage.abilities.keyword.LifelinkAbility;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import mage.game.permanent.Permanent;
import org.junit.Assert;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;

/**
 * @author noxx
 *
 * Card: You may have {this} enter the battlefield as a copy of any creature on
 * the battlefield, except it's an Illusion in addition to its other types and
 * it gains "When this creature becomes the target of a spell or ability,
 * sacrifice it."
 *
 */
public class PhantasmalImageTest extends CardTestPlayerBase {

    @Test
    public void testCopyCreature() {
        addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
        addCard(Zone.HAND, playerA, "Phantasmal Image");
        addCard(Zone.BATTLEFIELD, playerB, "Craw Wurm");

        castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Phantasmal Image");

        setStopAt(2, PhaseStep.END_TURN);
        execute();

        assertLife(playerA, 20);
        assertLife(playerB, 20);
        assertPermanentCount(playerA, "Craw Wurm", 1);
        assertPermanentCount(playerB, "Craw Wurm", 1);
    }

    /**
     * Tests that copy effect will copy EntersBattlefieldTriggeredAbility and it
     * will be applied.
     */
    @Test
    public void testCopyEntersBattlefieldTriggeredAbility() {
        addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
        addCard(Zone.HAND, playerA, "Phantasmal Image");
        addCard(Zone.BATTLEFIELD, playerB, "Howling Banshee");

        castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Phantasmal Image");

        setStopAt(2, PhaseStep.END_TURN);
        execute();

        assertPermanentCount(playerA, "Howling Banshee", 1);
        assertPermanentCount(playerB, "Howling Banshee", 1);

        assertLife(playerA, 17);
        assertLife(playerB, 17);
    }

    /**
     * Tests that copy won't have level up counters and will have zero level.
     */
    @Test
    public void testCopyCreatureWithLevelUpAbility() {
        addCard(Zone.BATTLEFIELD, playerA, "Transcendent Master");
        addCard(Zone.BATTLEFIELD, playerA, "Plains", 12);

        addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
        addCard(Zone.HAND, playerB, "Phantasmal Image");

        for (int i = 0; i < 12; i++) {
            activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Level up {1}");
        }

        castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Phantasmal Image");

        setStopAt(2, PhaseStep.END_TURN);
        execute();

        assertPermanentCount(playerA, "Transcendent Master", 1);
        assertPermanentCount(playerB, "Transcendent Master", 1);

        Permanent master = getPermanent("Transcendent Master", playerA.getId());
        Permanent masterCopied = getPermanent("Transcendent Master", playerB.getId());

        // Original master should be upgraded to 3rd level
        assertEquals("Power different", 9, master.getPower().getValue());
        assertEquals("Toughness different", 9, master.getToughness().getValue());
        assertTrue(master.getAbilities().contains(LifelinkAbility.getInstance()));
        assertTrue(master.getAbilities().containsRule(IndestructibleAbility.getInstance()));

        // But copied one should not
        assertEquals("Power different", 3, masterCopied.getPower().getValue());
        assertEquals("Toughness different", 3, masterCopied.getToughness().getValue());
        assertFalse(masterCopied.getAbilities().contains(LifelinkAbility.getInstance()));
        assertFalse(masterCopied.getAbilities().containsRule(IndestructibleAbility.getInstance()));
    }

    /**
     * Tests copying creature with BecomesTargetTriggeredAbility
     */
    @Test
    public void testCopyBecomesTargetTriggeredAbility() {
        addCard(Zone.BATTLEFIELD, playerA, "Island", 4);
        addCard(Zone.HAND, playerA, "Phantasmal Image", 2);
        addCard(Zone.BATTLEFIELD, playerA, "Illusionary Servant");

        setChoice(playerA, "Illusionary Servant");
        setChoice(playerA, "Illusionary Servant-M10");

        castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Phantasmal Image");
        castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Phantasmal Image");

        setStopAt(1, PhaseStep.END_TURN);
        execute();

        assertLife(playerA, 20);
        assertLife(playerB, 20);

        assertGraveyardCount(playerA, 0);
        assertPermanentCount(playerA, "Illusionary Servant", 3);
    }

    //  PhantasmalImageTest.testCopyAlreadyTransformed:143->
    //  CardTestPlayerAPIImpl.assertPowerToughness:351->CardTestPlayerAPIImpl.assertPowerToughness:337
    // There is no such creature under player's control with specified power&toughness, player=PlayerA,
    // cardName=Ravager of the Fells (found similar: 1, one of them: power=8 toughness=8)
    /**
     * Tests copying already transformed creature Makes sure it still has "When
     * this creature becomes the target of a spell or ability, sacrifice it"
     */
    @Test
    public void testCopyAlreadyTransformed() {
        addCard(Zone.BATTLEFIELD, playerA, "Forest", 5);
        addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
        addCard(Zone.BATTLEFIELD, playerB, "Forest", 2);
        addCard(Zone.HAND, playerB, "Phantasmal Image");
        // Target creature gets +4/+4 until end of turn.
        addCard(Zone.HAND, playerB, "Titanic Growth");

        // Enchantment - Creatures you control have hexproof.
        addCard(Zone.HAND, playerA, "Asceticism");

        // Whenever this creature enters the battlefield or transforms into
        // Huntmaster of the Fells, put a 2/2 green Wolf creature token onto
        // the battlefield and you gain 2 life.
        // At the beginning of each upkeep, if no spells were cast last turn, transform Huntmaster of the Fells. ==> Ravager of the Fells
        addCard(Zone.BATTLEFIELD, playerA, "Huntmaster of the Fells");

        castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Phantasmal Image"); // copy target: Ravergers of the Fells
        castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Asceticism");
        castSpell(3, PhaseStep.POSTCOMBAT_MAIN, playerB, "Titanic Growth", "Ravager of the Fells");

        setStopAt(3, PhaseStep.END_TURN);
        execute();

        assertLife(playerB, 18);
        // check opponent's creature wasn't chosen as a target for Titanic Growth
        assertPowerToughness(playerA, "Ravager of the Fells", 4, 4);
        assertGraveyardCount(playerB, "Titanic Growth", 1);
        // check playerB's creature was sacrificed
        assertGraveyardCount(playerB, "Phantasmal Image", 1);
        assertPermanentCount(playerB, "Ravager of the Fells", 0);

    }

    /**
     * Tests that copy of Geralf's Messenger also enters tapped Geralf's
     * Messenger: Geralf's Messenger enters the battlefield tapped
     */
    @Test
    public void testCopyEntersTapped() {
        addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
        // You may have Phantasmal Image enter the battlefield as a copy of any creature
        // on the battlefield, except it's an Illusion in addition to its other types and
        // it gains "When this creature becomes the target of a spell or ability, sacrifice it."
        addCard(Zone.HAND, playerA, "Phantasmal Image");
        addCard(Zone.BATTLEFIELD, playerB, "Geralf's Messenger");

        castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Phantasmal Image");

        setStopAt(1, PhaseStep.BEGIN_COMBAT);
        execute();

        Permanent copy = getPermanent("Geralf's Messenger", playerA.getId());
        Assert.assertNotNull(copy);
        Assert.assertTrue("Should be tapped", copy.isTapped());

        // Tests: When Geralf's Messenger enters the battlefield, target opponent loses 2 life.
        assertLife(playerB, 18);
    }

    /**
     * Tests that copy effect will copy AsEntersBattlefieldAbility and will
     * choose another color. As there is no permanent of the second color, copy
     * of Lurebound Scarecrow will be sacrificed.
     */
    @Test
    public void testCopyAsEntersBattlefieldAbility() {
        addCard(Zone.BATTLEFIELD, playerA, "Island", 5);
        addCard(Zone.BATTLEFIELD, playerA, "Llanowar Elves");
        addCard(Zone.HAND, playerA, "Phantasmal Image");

        // As Lurebound Scarecrow enters the battlefield, choose a color.
        // When you control no permanents of the chosen color, sacrifice Lurebound Scarecrow.
        addCard(Zone.HAND, playerA, "Lurebound Scarecrow");

        setChoice(playerA, "Green");
        castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lurebound Scarecrow");
        setChoice(playerA, "Red");
        castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Phantasmal Image");

        setStopAt(1, PhaseStep.END_TURN);
        execute();

        assertPermanentCount(playerA, "Lurebound Scarecrow", 1);
    }

    /**
     * Tests that copy effect will copy AsEntersBattlefieldAbility and will
     * choose another color. Both Lurebound Scarecrow cards should stay on
     * battlefield.
     */
    @Test
    public void testCopyAsEntersBattlefieldAbility2() {
        addCard(Zone.BATTLEFIELD, playerA, "Island", 5);
        addCard(Zone.BATTLEFIELD, playerA, "Llanowar Elves");
        addCard(Zone.BATTLEFIELD, playerA, "Raging Goblin");
        addCard(Zone.HAND, playerA, "Phantasmal Image");
        addCard(Zone.HAND, playerA, "Lurebound Scarecrow");

        setChoice(playerA, "Green");
        castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lurebound Scarecrow");
        setChoice(playerA, "Red");
        castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Phantasmal Image");

        setStopAt(1, PhaseStep.END_TURN);
        execute();

        assertPermanentCount(playerA, "Lurebound Scarecrow", 2);
    }

    @Test
    public void testCopiedFlyingWorks() {
        addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
        addCard(Zone.HAND, playerA, "Phantasmal Image");
        addCard(Zone.BATTLEFIELD, playerA, "Fervor");
        addCard(Zone.BATTLEFIELD, playerA, "Elite Vanguard");

        addCard(Zone.BATTLEFIELD, playerB, "Azure Drake");
        addCard(Zone.BATTLEFIELD, playerB, "Llanowar Elves");

        castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Phantasmal Image");
        attack(1, playerA, "Azure Drake");
        block(1, playerB, "Llanowar Elves", "Azure Drake");

        attack(2, playerB, "Azure Drake");
        block(2, playerA, "Elite Vanguard", "Azure Drake");

        setStopAt(2, PhaseStep.END_TURN);
        execute();

        assertLife(playerB, 18);
        assertLife(playerA, 18);
    }

    /**
     * I attack with a Phantasmal Image of Steel Hellkite. It deals damage. I
     * activate it for zero. A.I. has Chalice of the Void set to one counter.
     * The Chalice should be destroyed I think as in play it has a converted
     * mana cost of zero but it is not.
     */
    @Test
    public void testCopiedSteelHellkite() {
        addCard(Zone.BATTLEFIELD, playerA, "Steel Hellkite");
        addCard(Zone.HAND, playerA, "Chalice of the Void");

        addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
        addCard(Zone.HAND, playerB, "Phantasmal Image");

        castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Chalice of the Void");
        setChoice(playerA, "X=0");

        castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Phantasmal Image");
        setChoice(playerB, "Steel Hellkite");

        attack(4, playerB, "Steel Hellkite");

        activateAbility(4, PhaseStep.POSTCOMBAT_MAIN, playerB, "{X}: Destroy each nonland permanent with converted mana cost X whose controller was dealt combat damage by {this} this turn. Activate this ability only once each turn.");
        setChoice(playerB, "X=0");

        setStopAt(4, PhaseStep.END_TURN);
        execute();

        assertPermanentCount(playerA, "Steel Hellkite", 1);
        assertPermanentCount(playerB, "Steel Hellkite", 1);

        assertLife(playerB, 20);
        assertLife(playerA, 15);

        assertPermanentCount(playerA, "Chalice of the Void", 0);
        assertGraveyardCount(playerA, "Chalice of the Void", 1);

    }

    /**
     * I cast Phantasmal Image copying a Frost Titan and the image did not have
     * the "When this creature becomes the target of a spell or ability,
     * sacrifice it." ability. I did not pay attention to see if it failed to
     * become an illusion too.
     *
     */
    @Test
    public void testCopiedFrostTitan() {
        // Whenever Frost Titan becomes the target of a spell or ability an opponent controls, counter that spell or ability unless its controller pays {2}.
        // Whenever Frost Titan enters the battlefield or attacks, tap target permanent. It doesn't untap during its controller's next untap step.
        addCard(Zone.BATTLEFIELD, playerA, "Frost Titan");
        addCard(Zone.HAND, playerA, "Terror");
        // {1}{U} - Target creature gains shroud until end of turn and can't be blocked this turn.
        addCard(Zone.HAND, playerA, "Veil of Secrecy");
        addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
        addCard(Zone.BATTLEFIELD, playerA, "Island", 2);

        addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
        addCard(Zone.HAND, playerB, "Phantasmal Image");

        castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Phantasmal Image"); // not targeted
        castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Veil of Secrecy", "Frost Titan"); // so it's no longer targetable
        setChoice(playerB, "Frost Titan");

        castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerA, "Terror", "Frost Titan"); // of player Bs Phantasmal Image copying Frost Titan
        // should be countered if not paying {2}

        setStopAt(2, PhaseStep.END_TURN);
        execute();

        assertGraveyardCount(playerA, "Veil of Secrecy", 1);
        assertGraveyardCount(playerA, "Terror", 1);

        assertLife(playerB, 20);
        assertLife(playerA, 20);

        assertPermanentCount(playerA, "Frost Titan", 1);

        assertGraveyardCount(playerB, "Phantasmal Image", 1); // if triggered ability did not work, the Titan would be in the graveyard instaed

    }

    // I've casted a Phantasmal Image targeting opponent's Wurmcoil Engine
    // When my Phantasmal Image died, it didn't triggered the Wurmcoil Engine's last ability
    // (When Wurmcoil Engine dies, put a 3/3 colorless Wurm artifact creature token with deathtouch and
    // a 3/3 colorless Wurm artifact creature token with lifelink onto the battlefield.)
    @Test
    public void testDiesTriggeredAbilities() {
        addCard(Zone.BATTLEFIELD, playerA, "Wurmcoil Engine");
        // Destroy target creature an opponent controls. Each other creature that player controls gets -2/-0 until end of turn.
        addCard(Zone.HAND, playerA, "Public Execution");
        addCard(Zone.BATTLEFIELD, playerA, "Swamp", 6);

        addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
        addCard(Zone.HAND, playerB, "Phantasmal Image");

        castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Phantasmal Image"); // not targeted
        setChoice(playerB, "Wurmcoil Engine");

        castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerA, "Public Execution", "Wurmcoil Engine"); // of player Bs Phantasmal Image copying Frost Titan
        // should be countered if not paying {2}

        setStopAt(2, PhaseStep.END_TURN);
        execute();

        assertGraveyardCount(playerA, "Public Execution", 1);

        assertLife(playerB, 20);
        assertLife(playerA, 20);

        assertPermanentCount(playerA, "Wurmcoil Engine", 1);

        assertGraveyardCount(playerB, "Phantasmal Image", 1);
        assertPermanentCount(playerB, "Wurm", 2); // if triggered ability did not work, the Titan would be in the graveyard instaed

    }

    /**
     * Phantasmal Image is not regestering Leave the battlefield triggers,
     * persist and undying triggers
     */
    @Test
    public void testLeavesTheBattlefieldTriggeredAbilities() {
        // Shadow (This creature can block or be blocked by only creatures with shadow.)
        // When Thalakos Seer leaves the battlefield, draw a card.
        addCard(Zone.BATTLEFIELD, playerA, "Thalakos Seer");

        // Destroy target creature an opponent controls. Each other creature that player controls gets -2/-0 until end of turn.
        addCard(Zone.HAND, playerA, "Public Execution");
        addCard(Zone.BATTLEFIELD, playerA, "Swamp", 6);

        addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
        addCard(Zone.HAND, playerB, "Phantasmal Image");

        castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Phantasmal Image"); // not targeted
        setChoice(playerB, "Thalakos Seer");

        castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerA, "Public Execution", "Thalakos Seer");

        setStopAt(2, PhaseStep.END_TURN);
        execute();

        assertGraveyardCount(playerA, "Public Execution", 1);

        assertLife(playerB, 20);
        assertLife(playerA, 20);

        assertPermanentCount(playerA, "Thalakos Seer", 1);

        assertGraveyardCount(playerB, "Phantasmal Image", 1);

        assertHandCount(playerB, 2); // 1 from draw turn 2 and 1 from Thalakos Seer leaves the battlefield trigger
    }

    /**
     * Action Game State 1 -----------------> Game State 2 (On 'field) (Move to
     * GY) (In graveyard)
     *
     * LTB abilities such as Persist are expceptional in that they trigger based
     * on their existence and state of objects before the event (Game State 1,
     * when the card is on the battlefield) rather than after (Game State 2,
     * when the card is in the graveyard). It doesn't matter that the LTB
     * ability doesn't exist in Game State 2. [CR 603.6d]
     *
     * 603.6d Normally, objects that exist immediately after an event are
     * checked to see if the event matched any trigger conditions. Continuous
     * effects that exist at that time are used to determine what the trigger
     * conditions are and what the objects involved in the event look like.
     * However, some triggered abilities must be treated specially.
     * Leaves-the-battlefield abilities, abilities that trigger when a permanent
     * phases out, abilities that trigger when an object that all players can
     * see is put into a hand or library, abilities that trigger specifically
     * when an object becomes unattached, abilities that trigger when a player
     * loses control of an object, and abilities that trigger when a player
     * planeswalks away from a plane will trigger based on their existence, and
     * the appearance of objects, prior to the event rather than afterward. The
     * game has to “look back in time” to determine if these abilities trigger.
     *
     * Example: Two creatures are on the battlefield along with an artifact that
     * has the ability “Whenever a creature dies, you gain 1 life.” Someone
     * plays a spell that destroys all artifacts, creatures, and enchantments.
     * The artifact's ability triggers twice, even though the artifact goes to
     * its owner's graveyard at the same time as the creatures.
     *
     */
    @Test
    public void testPersist() {
        addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
        // When Kitchen Finks enters the battlefield, you gain 2 life.
        // Persist (When this creature dies, if it had no -1/-1 counters on it, return it to the battlefield under its owner's control with a -1/-1 counter on it.)
        addCard(Zone.HAND, playerA, "Kitchen Finks");

        // Destroy target creature an opponent controls. Each other creature that player controls gets -2/-0 until end of turn.
        addCard(Zone.HAND, playerA, "Public Execution");
        addCard(Zone.BATTLEFIELD, playerA, "Swamp", 6);

        addCard(Zone.BATTLEFIELD, playerB, "Island", 2);

        // You may have Phantasmal Image enter the battlefield as a copy of any creature
        // on the battlefield, except it's an Illusion in addition to its other types and
        // it gains "When this creature becomes the target of a spell or ability, sacrifice it."
        addCard(Zone.HAND, playerB, "Phantasmal Image");

        castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Kitchen Finks");

        castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Phantasmal Image"); // not targeted
        setChoice(playerB, "Kitchen Finks");

        castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerA, "Public Execution", "Kitchen Finks");
        setChoice(playerB, "Kitchen Finks");

        setStopAt(2, PhaseStep.END_TURN);
        execute();

        assertGraveyardCount(playerA, "Public Execution", 1);

        assertLife(playerA, 22);
        assertLife(playerB, 24);

        assertPermanentCount(playerA, "Kitchen Finks", 1);

        assertHandCount(playerB, "Phantasmal Image", 0);
        assertGraveyardCount(playerB, "Phantasmal Image", 0);
        assertPermanentCount(playerB, "Kitchen Finks", 1);
        assertPowerToughness(playerB, "Kitchen Finks", 2, 1);

    }

    @Test
    public void testUndying() {
        addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
        // Undying (When this creature dies, if it had no +1/+1 counters on it, return it to the battlefield under its owner's control with a +1/+1 counter on it.)
        addCard(Zone.HAND, playerA, "Butcher Ghoul");

        // Destroy target creature an opponent controls. Each other creature that player controls gets -2/-0 until end of turn.
        addCard(Zone.HAND, playerA, "Public Execution");
        addCard(Zone.BATTLEFIELD, playerA, "Swamp", 6);

        addCard(Zone.BATTLEFIELD, playerB, "Island", 2);

        // You may have Phantasmal Image enter the battlefield as a copy of any creature
        // on the battlefield, except it's an Illusion in addition to its other types and
        // it gains "When this creature becomes the target of a spell or ability, sacrifice it."
        addCard(Zone.HAND, playerB, "Phantasmal Image");

        castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Butcher Ghoul");

        castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Phantasmal Image"); // not targeted
        setChoice(playerB, "Butcher Ghoul");

        castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerA, "Public Execution", "Butcher Ghoul");
        setChoice(playerB, "Butcher Ghoul");

        setStopAt(2, PhaseStep.END_TURN);
        execute();

        assertGraveyardCount(playerA, "Public Execution", 1);

        assertLife(playerA, 20);
        assertLife(playerB, 20);

        assertPermanentCount(playerA, "Butcher Ghoul", 1);

        assertHandCount(playerB, "Phantasmal Image", 0);
        assertGraveyardCount(playerB, "Phantasmal Image", 0);
        assertPermanentCount(playerB, "Butcher Ghoul", 1);
        assertPowerToughness(playerB, "Butcher Ghoul", 2, 2);

    }

    /**
     * 12:29: Attacker: Wurmcoil Engine [466] (6/6) blocked by Wurmcoil Engine
     * [4ed] (6/6) 12:29: yespair gains 6 life 12:29: HipSomHap gains 6 life
     * 12:29: Wurmcoil Engine [4ed] died 12:29: Ability triggers: Wurmcoil
     * Engine [4ed] - When Wurmcoil Engine [4ed] dies, put a a 3/3 colorless
     * Wurm artifact creature token with deathtouch onto the battlefield. Put a
     * a 3/3 colorless Wurm artifact creature token with lifelink onto the
     * battlefield. 12:29: Phantasmal Image [466] died 12:29: HipSomHap puts a
     * Wurm [7d0] token onto the battlefield 12:29: HipSomHap puts a Wurm [186]
     * token onto the battlefield
     *
     * To the best of my knowledge, the Phantasmal Image [466], which entered
     * the battlefield as a Wurmcoil Engine, should grant tokens through the
     * Dies-trigger as well, right?
     */
    @Test
    public void testDiesTriggered2() {
        addCard(Zone.BATTLEFIELD, playerB, "Wurmcoil Engine");

        addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
        addCard(Zone.HAND, playerA, "Phantasmal Image");

        castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Phantasmal Image"); // not targeted
        setChoice(playerB, "Wurmcoil Engine");

        attack(2, playerB, "Wurmcoil Engine");
        block(2, playerA, "Wurmcoil Engine", "Wurmcoil Engine");
        setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
        execute();

        assertLife(playerB, 26);
        assertLife(playerA, 26);

        assertGraveyardCount(playerA, "Phantasmal Image", 1);
        assertGraveyardCount(playerB, "Wurmcoil Engine", 1);

        assertPermanentCount(playerA, "Wurm", 2);
        assertPermanentCount(playerB, "Wurm", 2);

    }

    /**
     * A Phantasmal Image that was copying a Voice of Resurgence died and left
     * no token behind.
     */
    @Test
    public void testVoiceOfResurgence() {
        // Whenever an opponent casts a spell during your turn or when Voice of Resurgence dies, put a green and white Elemental creature token onto the battlefield with "This creature's power and toughness are each equal to the number of creatures you control."
        addCard(Zone.BATTLEFIELD, playerB, "Voice of Resurgence");

        addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
        addCard(Zone.HAND, playerA, "Phantasmal Image");

        castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Phantasmal Image"); // not targeted
        setChoice(playerB, "Voice of Resurgence");

        attack(2, playerB, "Voice of Resurgence");
        block(2, playerA, "Voice of Resurgence", "Voice of Resurgence");
        setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
        execute();

        assertLife(playerB, 20);
        assertLife(playerA, 20);

        assertGraveyardCount(playerA, "Phantasmal Image", 1);
        assertGraveyardCount(playerB, "Voice of Resurgence", 1);

        assertPermanentCount(playerB, "Elemental", 1);
        assertPermanentCount(playerA, "Elemental", 1);

    }
}
