package game_test

import (
	"testing"

	"galaxy/game/internal/model/game"

	"github.com/stretchr/testify/assert"
)

func TestPlanetProduction(t *testing.T) {
	assert.Equal(t, 1000., game.PlanetProduction(1000., 1000.))
	assert.Equal(t, 625., game.PlanetProduction(500., 1000.))
	assert.Equal(t, 750., game.PlanetProduction(1000., 0.))
	assert.Equal(t, 250., game.PlanetProduction(0., 1000.))
}

func TestProduceIndustry(t *testing.T) {
	HW := &game.Planet{
		Size:       1000,
		Resources:  10,
		Population: 1000,
		Industry:   1000,
	}
	DW := &game.Planet{
		Size:       500,
		Resources:  10,
		Population: 500,
		Industry:   500,
	}
	HW.ProduceIndustry(HW.ProductionCapacity())
	assert.InDelta(t, 196.078, HW.Capital.F(), 0.0005)

	HW.Capital = 0
	HW.Material = 200

	HW.ProduceIndustry(HW.ProductionCapacity())
	assert.Equal(t, 200., HW.Capital.F())
	assert.Equal(t, 0., HW.Material.F())

	DW.ProduceIndustry(DW.ProductionCapacity())
	assert.InDelta(t, 98.039, DW.Capital.F(), 0.0003)

	DW.Capital = 0
	DW.Material = 100

	DW.ProduceIndustry(DW.ProductionCapacity())
	assert.Equal(t, 100., DW.Capital.F())
	assert.Equal(t, 0., DW.Material.F())
}

func TestProduceMaterial(t *testing.T) {
	HW := &game.Planet{
		Size:       1000,
		Resources:  10,
		Population: 1000,
		Industry:   1000,
	}
	assert.Equal(t, 0., HW.Material.F())

	HW.ProduceMaterial(HW.ProductionCapacity())
	assert.Equal(t, 10000., HW.Material.F())

	HW.Industry = 500
	HW.Population = 500
	HW.ProduceMaterial(HW.ProductionCapacity())
	assert.Equal(t, 15000., HW.Material.F())

	HW.Population = 1000
	HW.ProduceMaterial(HW.ProductionCapacity())
	assert.Equal(t, 21250., HW.Material.F())
}

func TestUnpackCapital(t *testing.T) {
	HW := &game.Planet{
		Size:       1000,
		Resources:  10,
		Population: 1000,
		Industry:   1000,
	}
	assert.Equal(t, 0., HW.Capital.F())

	HW.UnpackCapital()
	assert.Equal(t, 1000., HW.Industry.F())
	assert.Equal(t, 0., HW.Capital.F())

	HW.Capital = 123.
	HW.UnpackCapital()
	assert.Equal(t, 1000., HW.Industry.F())
	assert.Equal(t, 123., HW.Capital.F())

	HW.Industry = 987.
	HW.UnpackCapital()
	assert.Equal(t, 1000., HW.Industry.F())
	assert.Equal(t, 110., HW.Capital.F())

	HW.Population = 876.
	HW.Industry = 800.
	HW.UnpackCapital()
	assert.Equal(t, 876., HW.Population.F())
	assert.Equal(t, 876., HW.Industry.F())
	assert.Equal(t, 34., HW.Capital.F())
}

func TestUnpackColonists(t *testing.T) {
	HW := &game.Planet{
		Size:       1000,
		Resources:  10,
		Population: 1000,
		Industry:   1000,
	}
	assert.Equal(t, 0., HW.Colonists.F())

	HW.UnpackColonists()
	assert.Equal(t, 1000., HW.Population.F())
	assert.Equal(t, 0., HW.Colonists.F())

	HW.Colonists = 1.05
	HW.UnpackColonists()
	assert.Equal(t, 1000., HW.Population.F())
	assert.Equal(t, 1.05, HW.Colonists.F())

	HW.Population = 996.0
	HW.UnpackColonists()
	assert.Equal(t, 1000., HW.Population.F())
	assert.Equal(t, 0.55, HW.Colonists.F())

	HW.Population = 0.0
	HW.UnpackColonists()
	assert.Equal(t, 4.4, HW.Population.F())
	assert.Equal(t, 0., HW.Colonists.F())
}

func TestProducePopulation(t *testing.T) {
	HW := &game.Planet{
		Size:       1000,
		Resources:  10,
		Population: 500,
		Industry:   1000,
	}
	assert.Equal(t, 500., HW.Population.F())
	assert.Equal(t, 0., HW.Colonists.F())

	HW.ProducePopulation()
	assert.Equal(t, 540., HW.Population.F())
	assert.Equal(t, 0., HW.Colonists.F())

	HW.Population = 1000.
	HW.ProducePopulation()
	assert.Equal(t, 1000., HW.Population.F())
	assert.Equal(t, 10., HW.Colonists.F())
}
