package traits;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.ArrayList;
import java.util.UUID;

import org.junit.Test;

import traits.TraitManager.TraitHost;

public class TraitManagerTest {

	interface Entity {
		String id();
	}
	static class EntityTrait implements TraitManager.Trait {

		@Override
		public void augment(TraitHost host) {
			String id = UUID.randomUUID()
				.toString();
			host.addInstance(Entity.class, () -> id);
		}

		@Override
		public boolean handles(Class<?> c) {
			return c == Entity.class;
		}

	}

	interface Position {
		int x();
		int y();

		void xy(int x, int y);
	}
	static class PositionTrait implements TraitManager.Trait {
		static class PositionImpl implements Position {
			int x, y;
			@Override
			public int x() {
				return x;
			}

			@Override
			public int y() {
				return y;
			}

			@Override
			public void xy(int x, int y) {
				this.x = x;
				this.y = y;
			}

		}
		@Override
		public void augment(TraitHost host) {
			host.addInstance(Position.class, new PositionImpl());
		}

		@Override
		public boolean handles(Class<?> c) {
			return c == Position.class;
		}

	}

	interface View extends Entity, Position {

	}

	@Test
	public void testSimple() {
		TraitManager tm = new TraitManager();
		tm.traits = new ArrayList<>();
		tm.traits.add(new EntityTrait());
		tm.traits.add(new PositionTrait());

		View view = tm.create(View.class);
		assertThat(view.x()).isEqualTo(0);
		assertThat(view.id()).isNotNull();

		view.xy(42, 24);
		assertThat(view.x()).isEqualTo(42);
		assertThat(view.y()).isEqualTo(24);
	}
}
