package de.tu_dresden.diplom.richter_mirko_mat2628335.witness.account;

import junit.framework.TestCase;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.account.Amount;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.account.IFCurrency;

/**
 * Created by IntelliJ IDEA.
 * User: mr22
 * Date: 12.04.2005
 * Time: 20:18:55
 * To change this template use File | Settings | File Templates.
 */
public class UTAccountTransferContext extends TestCase {

   protected void setUp() throws Exception {
   }

   protected void tearDown() throws Exception {
   }

   public void testInstance() {
      {
         // Normal account life
         Account source = new Account(new Amount(100, IFCurrency.CURRENCY_COUNTER_INST));
         Account target = new Account(new Amount(15, IFCurrency.CURRENCY_COUNTER_INST));
         Amount transferValue = new Amount(20, IFCurrency.CURRENCY_COUNTER_INST);
         AccountTransferContext acc1 = new AccountTransferContext(source, target, transferValue);
         assertTrue(acc1.isValid());
      }
      {
         // negative transfervalue not allowed
         Account source = new Account(new Amount(100, IFCurrency.CURRENCY_COUNTER_INST));
         Account target = new Account(new Amount(15, IFCurrency.CURRENCY_COUNTER_INST));
         Amount transferValue = new Amount(-20, IFCurrency.CURRENCY_COUNTER_INST);
         AccountTransferContext acc1 = new AccountTransferContext(source, target, transferValue);
         assertFalse(acc1.isValid());
      }
      {
         // NULL is not allowed
         Account source = new Account(new Amount(100, IFCurrency.CURRENCY_COUNTER_INST));
         Account target = new Account(new Amount(15, IFCurrency.CURRENCY_COUNTER_INST));
         Amount transferValue = new Amount(20, IFCurrency.CURRENCY_COUNTER_INST);
         AccountTransferContext acc1 = new AccountTransferContext(null, target, transferValue);
         assertFalse(acc1.isValid());
         acc1 = new AccountTransferContext(source, null, transferValue);
         assertFalse(acc1.isValid());
         acc1 = new AccountTransferContext(source, target, null);
         assertFalse(acc1.isValid());
      }
      {
         // too large debit without credit
         Account source = new Account(new Amount(15, IFCurrency.CURRENCY_COUNTER_INST));
         Account target = new Account(new Amount(30, IFCurrency.CURRENCY_COUNTER_INST));
         Amount transferValue = new Amount(20, IFCurrency.CURRENCY_COUNTER_INST);
         AccountTransferContext acc1 = new AccountTransferContext(source, target, transferValue);
         assertFalse(acc1.isValid());

         // adding credit -> now it should work
         source.setCredit(new Amount(50, IFCurrency.CURRENCY_COUNTER_INST));
         acc1 = new AccountTransferContext(source, target, transferValue);
         assertTrue(acc1.isValid());

         // still enough to add this debit
         transferValue = new Amount(40, IFCurrency.CURRENCY_COUNTER_INST);
         acc1 = new AccountTransferContext(source, target, transferValue);
         assertTrue(acc1.isValid());

         // not enough anymore to add this debit
         transferValue = new Amount(40, IFCurrency.CURRENCY_COUNTER_INST);
         acc1 = new AccountTransferContext(source, target, transferValue);
         assertFalse(acc1.isValid());
      }
   }

   public void testAccountState() {
      Account source = new Account(new Amount(100, IFCurrency.CURRENCY_COUNTER_INST));
      Account target = new Account(new Amount(15, IFCurrency.CURRENCY_COUNTER_INST));
      Amount transferValue = new Amount(20, IFCurrency.CURRENCY_COUNTER_INST);
      AccountTransferContext acc1 = new AccountTransferContext(source, target, transferValue);
      assertTrue(acc1.isValid());

      assertEquals(source.getVirtualCreditSum().getAmount(), 0, 0);
      assertEquals(source.getVirtualDebitSum().getAmount(), 20, 0);
      assertEquals(source.getAmount().getAmount(), 100, 0);
      assertEquals(target.getVirtualCreditSum().getAmount(), 20, 0);
      assertEquals(target.getVirtualDebitSum().getAmount(), 0, 0);
      assertEquals(target.getAmount().getAmount(), 15, 0);

      transferValue = new Amount(20, IFCurrency.CURRENCY_COUNTER_INST);
      acc1 = new AccountTransferContext(source, target, transferValue);
      assertTrue(acc1.isValid());

      assertEquals(source.getVirtualCreditSum().getAmount(), 0, 0);
      assertEquals(source.getVirtualDebitSum().getAmount(), 40, 0);
      assertEquals(source.getAmount().getAmount(), 100, 0);
      assertEquals(target.getVirtualCreditSum().getAmount(), 40, 0);
      assertEquals(target.getVirtualDebitSum().getAmount(), 0, 0);
      assertEquals(target.getAmount().getAmount(), 15, 0);

      // not enough amount
      transferValue = new Amount(70, IFCurrency.CURRENCY_COUNTER_INST);
      acc1 = new AccountTransferContext(source, target, transferValue);
      assertFalse(acc1.isValid());

      assertEquals(source.getVirtualCreditSum().getAmount(), 0, 0);
      assertEquals(source.getVirtualDebitSum().getAmount(), 40, 0);
      assertEquals(source.getAmount().getAmount(), 100, 0);
      assertEquals(target.getVirtualCreditSum().getAmount(), 40, 0);
      assertEquals(target.getVirtualDebitSum().getAmount(), 0, 0);
      assertEquals(target.getAmount().getAmount(), 15, 0);

      transferValue = new Amount(20, IFCurrency.CURRENCY_COUNTER_INST);
      acc1 = new AccountTransferContext(source, target, transferValue);
      assertTrue(acc1.isValid());

      assertEquals(source.getVirtualCreditSum().getAmount(), 0, 0);
      assertEquals(source.getVirtualDebitSum().getAmount(), 60, 0);
      assertEquals(source.getAmount().getAmount(), 100, 0);
      assertEquals(target.getVirtualCreditSum().getAmount(), 60, 0);
      assertEquals(target.getVirtualDebitSum().getAmount(), 0, 0);
      assertEquals(target.getAmount().getAmount(), 15, 0);
   }

   public void testStartTransfer(){
      Account source = new Account(new Amount(100, IFCurrency.CURRENCY_COUNTER_INST));
      Account target = new Account(new Amount(15, IFCurrency.CURRENCY_COUNTER_INST));
      Amount transferValue = new Amount(20, IFCurrency.CURRENCY_COUNTER_INST);
      AccountTransferContext acc1 = new AccountTransferContext(source, target, transferValue);
      assertTrue(acc1.isValid());

      assertEquals(source.getVirtualCreditSum().getAmount(), 0, 0);
      assertEquals(source.getVirtualDebitSum().getAmount(), 20, 0);
      assertEquals(source.getAmount().getAmount(), 100, 0);
      assertEquals(target.getVirtualCreditSum().getAmount(), 20, 0);
      assertEquals(target.getVirtualDebitSum().getAmount(), 0, 0);
      assertEquals(target.getAmount().getAmount(), 15, 0);

      acc1.startTransfer();

      assertEquals(source.getVirtualCreditSum().getAmount(), 0, 0);
      assertEquals(source.getVirtualDebitSum().getAmount(), 0, 0);
      assertEquals(source.getAmount().getAmount(), 80, 0);
      assertEquals(target.getVirtualCreditSum().getAmount(), 0, 0);
      assertEquals(target.getVirtualDebitSum().getAmount(), 0, 0);
      assertEquals(target.getAmount().getAmount(), 35, 0);
   }

   public void testStopTransfer(){
      Account source = new Account(new Amount(100, IFCurrency.CURRENCY_COUNTER_INST));
      Account target = new Account(new Amount(15, IFCurrency.CURRENCY_COUNTER_INST));
      Amount transferValue = new Amount(20, IFCurrency.CURRENCY_COUNTER_INST);
      AccountTransferContext acc1 = new AccountTransferContext(source, target, transferValue);
      assertTrue(acc1.isValid());

      assertEquals(source.getVirtualCreditSum().getAmount(), 0, 0);
      assertEquals(source.getVirtualDebitSum().getAmount(), 20, 0);
      assertEquals(source.getAmount().getAmount(), 100, 0);
      assertEquals(target.getVirtualCreditSum().getAmount(), 20, 0);
      assertEquals(target.getVirtualDebitSum().getAmount(), 0, 0);
      assertEquals(target.getAmount().getAmount(), 15, 0);

      acc1.stopTransfer();

      assertEquals(source.getVirtualCreditSum().getAmount(), 0, 0);
      assertEquals(source.getVirtualDebitSum().getAmount(), 0, 0);
      assertEquals(source.getAmount().getAmount(), 100, 0);
      assertEquals(target.getVirtualCreditSum().getAmount(), 0, 0);
      assertEquals(target.getVirtualDebitSum().getAmount(), 0, 0);
      assertEquals(target.getAmount().getAmount(), 15, 0);
   }

   public void testTransfer() {
      Account source = new Account(new Amount(100, IFCurrency.CURRENCY_COUNTER_INST));
      Account target = new Account(new Amount(15, IFCurrency.CURRENCY_COUNTER_INST));
      Amount transferValue = new Amount(20, IFCurrency.CURRENCY_COUNTER_INST);
      AccountTransferContext transferContext = new AccountTransferContext(source, target, transferValue);
   }

}
