package net.ranides.assira.reflection.walker;

import net.ranides.test.TestFiles;
import net.ranides.assira.junit.NewAssert;
import net.ranides.assira.reflection.walker.WalkerContexts.ObjectContext;
import org.junit.Test;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.List;

import static net.ranides.test.mockup.reflection.ForObjectWalker.*;

public class ObjectWalkerTest {

    @Test
    public void basic() {
        StringWriter writer = new StringWriter();
        PrintWriter printer = new PrintWriter(writer);
        ObjectWalker.walk(FOO1, new ObjectVisitor.SimpleVisitor() {
            @Override
            public boolean visitObject(ObjectContext ctx) {
                printer.printf(
                    " - [%-12s] %-40s | %s = %s%n",
                    ctx.getClass().getSimpleName(),
                    ctx.typePath(),
                    ctx.namePath(),
                    ctx.value()
                );

                if (ctx.value() instanceof String) {
                    return false;
                }
                return true;
            }
        });
        NewAssert.assertLineEquals(TestFiles.WALK_BASIC, writer.toString());
    }

    @Test
    public void visitors() {
        StringWriter writer = new StringWriter();
        PrintWriter printer = new PrintWriter(writer);

        ObjectWalker.walk(FOO1, new ObjectVisitor.SimpleVisitor() {
            @Override
            public boolean visitObject(ObjectContext ctx) {
                printer.printf(" - [%-12s] %-40s | %s = %s%n",
                    ctx.getClass().getSimpleName(),
                    ctx.typePath(),
                    ctx.namePath(),
                    ctx.value()
                );

                if(ctx.value() instanceof String) {
                    return false;
                }

                return true;
            }
        });
        NewAssert.assertLineEquals(TestFiles.WALK_VISITORS, writer.toString());
    }

    @Test
    public void recursive() {
        StringWriter writer = new StringWriter();
        PrintWriter printer = new PrintWriter(writer);

        List<Foo> list = Arrays.asList(FOO2, FOO3, FOO2, FOO4);

        ObjectWalker.walk(list, ctx -> {
            printer.printf(" - [%-12s] %8s %-50s | %s = %s%n",
                ctx.getClass().getSimpleName(),
                ctx.isVisited(),
                ctx.typePath(),
                ctx.namePath(),
                ctx.value()
            );

            if(ctx.value() instanceof String) {
                return false;
            }
            if(ctx.isVisited()) {
                return false;
            }
            return true;
        });

        NewAssert.assertLineEquals(TestFiles.WALK_RECURSIVE, writer.toString());
    }

}