package pool

import (
	"fmt"
	"strconv"
	"sync"
	"sync/atomic"
	"testing"
	"time"
)

func TestApply(t *testing.T) {
	fmt.Println("TestApply begin")
	pool := NewWorkerPool(10, "test")
	result := int32(0)
	const TRUE_RESULT = 5050
	for i := int32(0); i <= 100; i++ {
		curval := i
		fnAdd := func() {
			atomic.AddInt32(&result, curval)
			fmt.Println(curval)
		}
		pool.Apply(fnAdd)
	}
	pool.WaitFinished()
	fmt.Println(result)
	if TRUE_RESULT != result {
		t.Fatalf("TestApply error, skip next step.")
		return
	}
	t.Logf("TestApply is success")
}

func TestHasWorker(t *testing.T) {
	pool := NewWorkerPool(10, "test")

	if !pool.HasWorker() {
		t.Fatalf("TestHasWorker error, skip next step.")
		return
	}
	t.Logf("TestHasWorker is success")
}

func TestApplyChan(t *testing.T) {
	fmt.Println("TestApplyChan begin")

	sqlChan := make(chan string, 10)

	pool0 := NewWorkerPool(10, "createSql")
	pool1 := NewWorkerPool(10, "ExecSql")

	go func() {
		for i := 0; i <= 100; i++ {
			value := strconv.Itoa(i)
			pool0.Apply(func() {
				sqlChan <- "select " + value + " from dual"
			})
		}
	}()

	go func() {
		for sql := range sqlChan {
			pool1.Apply(func() {
				fmt.Println(sql)
			})
		}
	}()

	pool0.WaitFinished()
	pool1.WaitFinished()
	t.Logf("TestApplyChan is success")
}

func TestWriteChan2(t *testing.T) {
	var wg sync.WaitGroup
	chan1 := make(chan int32, 10)

	const TRUE_RESULT = 1090
	num := int32(0)

	wg.Add(1)
	//协程1:生产者
	go func() {
		for i := int32(0); i < 10; i++ {
			chan1 <- i
			time.Sleep(time.Second)
		}
		fmt.Println("finish1")
		wg.Done()
	}()

	wg.Add(1)
	//协程2:生产者
	go func() {
		for i := int32(100); i < 110; i++ {
			chan1 <- i
			time.Sleep(time.Second)
		}
		wg.Done()
		fmt.Println("finish2")
	}()

	//消费chan1
	go func() {
		for i := range chan1 {
			fmt.Println(i)
			atomic.AddInt32(&num, i)
		}
	}()

	wg.Wait()
	close(chan1)

	fmt.Print(num)
	if TRUE_RESULT != num {
		t.Fatalf("TestWriteChan2 error")
	}
	t.Logf("TestWriteChan2 is success")

}

func TestChan(t *testing.T) {
	//var wg sync.WaitGroup
	genSqlPool := NewWorkerPool(10, "genSqlPool")
	chan1 := make(chan int, 10)

	go func() {
		for i := 0; i < 100; i++ {
			curval := i
			genSqlPool.Apply(func() {
				chan1 <- curval
			})
		}
	}()
	genSqlPool.WaitFinished()
	close(chan1)
}
