package com.turlir.translator;

import com.turlir.converter.Member;
import com.turlir.converter.Part;
import com.turlir.converter.Parts;
import com.turlir.converter.Value;
import com.turlir.interpreter.NotationInterpreter;

import org.hamcrest.CoreMatchers;
import org.junit.Before;
import org.junit.Test;

import java.util.Arrays;
import java.util.Iterator;
import java.util.Queue;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

public class PolishTranslatorTest {

    private static final Member OS = Parts.OS;

    private static final Part CS = Parts.CS;

    private static final Member PLUS = new Part("+", 2) {
        @Override
        public void process(NotationInterpreter interpreter) {
            Double a = interpreter.poolDigit();
            Double b = interpreter.poolDigit();
            interpreter.pushDigit(a + b);
        }
    };

    private static final Member MINUS = new Part("-", 2) {
        @Override
        public void process(NotationInterpreter interpreter) {
            Double a = interpreter.poolDigit();
            Double b = interpreter.poolDigit();
            interpreter.pushDigit(a - b);
        }
    };

    private static final Member MULTI = new Part("*", 3) {
        @Override
        public void process(NotationInterpreter interpreter) {
            Double a = interpreter.poolDigit();
            Double b = interpreter.poolDigit();
            interpreter.pushDigit(a * b);
        }
    };

    private static final Member DIV = new Part("/", 3) {
        @Override
        public void process(NotationInterpreter interpreter) {
            Double a = interpreter.poolDigit();
            Double b = interpreter.poolDigit();
            interpreter.pushDigit(a / b);
        }
    };

    private NotationTranslator sor;

    @Before
    public void setup() {
        sor = new PolishTranslator();
    }

    @Test
    public void plusTest() {
        Iterator<Member> sequence = seq(new Value(2), PLUS, new Value(3));
        Queue<Member> lst = sor.translate(sequence);
        check(lst, new Value(2), new Value(3), PLUS);
    }

    @Test
    public void priorityTest() {
        Iterator<Member> sequence = seq(new Value(2), PLUS, new Value(3), MULTI, new Value(7), MINUS, new Value(4), DIV, new Value(2));
        Queue<Member> lst = sor.translate(sequence);
        check(lst, new Value(2), new Value(3), new Value(7), MULTI, PLUS, new Value(4), new Value(2), DIV, MINUS);
    }

    @Test
    public void bracketTest() {
        Iterator<Member> sequence = seq(new Value(2), PLUS, OS, new Value(6), MINUS, new Value(5), CS);
        Queue<Member> lst = sor.translate(sequence);
        check(lst, new Value(2), new Value(6),  new Value(5), MINUS, PLUS);

        sequence = seq(new Value(2), PLUS, OS, new Value(6), MINUS, new Value(4), CS, MULTI, new Value(3));
        lst = sor.translate(sequence);
        check(lst, new Value(2), new Value(6),  new Value(4), MINUS, new Value(3), MULTI, PLUS);
    }

    private static void check(Queue<Member> actual, Member... exp) {
        assertNotNull(actual);
        assertEquals(exp.length, actual.size());
        assertThat(actual, CoreMatchers.hasItems(exp));
    }

    private static Iterator<Member> seq(Member... member) {
        return Arrays.asList(member).iterator();
    }

}
@@ -692,24 +692,28 @@
  PLUS = new 
+Stub
 Part(%22+%22, 2)
@@ -716,245 +716,8 @@
 , 2)
- %7B%0A        @Override%0A        public void process(NotationInterpreter interpreter) %7B%0A            Double a = interpreter.poolDigit();%0A            Double b = interpreter.poolDigit();%0A            interpreter.pushDigit(a + b);%0A        %7D%0A    %7D
 ;%0A%0A 
@@ -755,24 +755,28 @@
 MINUS = new 
+Stub
 Part(%22-%22, 2)
@@ -779,245 +779,8 @@
 , 2)
- %7B%0A        @Override%0A        public void process(NotationInterpreter interpreter) %7B%0A            Double a = interpreter.poolDigit();%0A            Double b = interpreter.poolDigit();%0A            interpreter.pushDigit(a - b);%0A        %7D%0A    %7D
 ;%0A%0A 
@@ -818,24 +818,28 @@
 MULTI = new 
+Stub
 Part(%22*%22, 3)
@@ -842,245 +842,8 @@
 , 3)
- %7B%0A        @Override%0A        public void process(NotationInterpreter interpreter) %7B%0A            Double a = interpreter.poolDigit();%0A            Double b = interpreter.poolDigit();%0A            interpreter.pushDigit(a * b);%0A        %7D%0A    %7D
 ;%0A%0A 
@@ -883,16 +883,20 @@
 V = new 
+Stub
 Part(%22/%22
@@ -903,245 +903,8 @@
 , 3)
- %7B%0A        @Override%0A        public void process(NotationInterpreter interpreter) %7B%0A            Double a = interpreter.poolDigit();%0A            Double b = interpreter.poolDigit();%0A            interpreter.pushDigit(a / b);%0A        %7D%0A    %7D
 ;%0A%0A 
@@ -2459,9 +2459,306 @@
 %0A    %7D%0A%0A
+    private static class StubPart extends Part %7B%0A%0A        private StubPart(String token, int priority) %7B%0A            super(token, priority);%0A        %7D%0A%0A        @Override%0A        public void process(NotationInterpreter interpreter) %7B%0A            throw new IllegalStateException();%0A        %7D%0A    %7D%0A%0A
 %7D

fix PolishTranslatorTest