// account-para-data.go provides an example of race conditions and data races if ran in a concurrent way
// If this program is ran sequentially then everythin is fine but once the program is ran in parallel
// is when problems could arise.
//
// Few terms to know:
//
// 1. A **race condition** is a situation, in which the result of an operation depends on the interleaving of certain individual operations.
//
// 2. A  **data race** is a situtation when at least two threads access a shared variable at the same time. One thread must try to modify the variable.
//
package main

import (
	"fmt"
	"sync"
)

type Account struct {
	balance int
}

func transfer(amount int, from *Account, to *Account, group *sync.WaitGroup) {

	if from.balance >= amount {
		from.balance -= amount
		to.balance += amount
	}
	group.Done()
}

func main() {

	account1 := Account{100}
	account2 := Account{100}

	var group sync.WaitGroup

	for i := 0; i < 100; i++ {
		group.Add(2)
		go transfer(1, &account1, &account2, &group)
		go transfer(1, &account2, &account1, &group)
	}
	group.Wait()
	fmt.Println("Account1 Balance = $", account1.balance)
	fmt.Println("Account2 Balance = $", account2.balance)

}
