/*
 * @author Ranides Atterwim <ranides@gmail.com>
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */
package net.ranides.assira.text;

import java.io.IOException;
import java.util.Locale;
import net.ranides.assira.trace.LoggerUtils;

import org.junit.Test;
import static org.junit.Assert.*;

/**
 *
 * @author ranides
 */
public class PrintPatternTest {
    
    private final PrintPatternFactory fformat;
    
    public PrintPatternTest() {
        LoggerUtils.initTest();
        
        fformat = new PrintPatternFactory()
            .configure('s', PrintFunction.PrintString.INSTANCE)
            .configure('d', PrintFunction.PrintNumberDec.INSTANCE)
            .configure('f', PrintFunction.PrintNumberFP.INSTANCE)
            .configure('t', new PrintText());
    }

    @Test
    public void testCompile() {
        
        PrintPattern pattern = fformat.compile("Hello %-'.8s :> %% ! %3$07.2f :) %f %1$d");
        
        assertEquals("Hello world... :> %% ! 0019.65 :) 3.141593 14", pattern.format("world", 14, 3.1415926, 19.6451));
        
        assertEquals("ŹREBIĘ zjada ćmę", fformat.compile("%ut zjada %lt").format("ŹrEbIę", "ĆmĘ"));

        assertEquals("add 2 3 eq", fformat.compile("add %d %d eq").format(2,3));
        assertEquals("add 5 8 eq", fformat.compile("add %d %d eq").format(5,8));
        
        // Error handling is poor, because our parser is "too generic".
        // We have to be "very generic" if we want to accept user-defined 
        // arguments for user-defined formatters. We could check correctness 
        // inside "PrintParams.ClassicParams" constructor but... we don't care
        assertEquals("hello world", fformat.compile("hello %x?#qqw$sorld").format("w"));
        
        try {
            // after %  we don't have any letters mappable to formatter
            fformat.compile("add %xarme").format("!");
            fail("Exception expected.");
        } catch(IllegalArgumentException ex) {
            assertNotNull(ex);
        }
    }
    
    private static final class PrintText implements PrintFunction {

        @Override
        public void apply(Appendable target, PrintParams params, Object[] values) throws IOException {
            String text = String.valueOf(values[params.index()]);
            switch (params.params()) {
                case "l":
                    target.append(text.toLowerCase(new Locale("pl")));
                    break;
                case "u":
                    target.append(text.toUpperCase(new Locale("pl")));
                    break;
                default:
                    target.append(text);
                    break;
            }
        }

        @Override
        public int estimate(PrintParams params, Object[] values) {
            return String.valueOf(values[params.index()]).length();
        }
        
    }
}
