/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.facebook.presto.spi.type;

import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import org.testng.annotations.Test;

import java.util.List;

import static com.facebook.presto.spi.type.TypeSignature.parseTypeSignature;
import static java.util.Locale.ENGLISH;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail;

public class TestTypeSignature
{
    @Test
    public void test()
            throws Exception
    {
        assertSignature("bigint", ImmutableList.<String>of());
        assertSignature("boolean", ImmutableList.<String>of());
        assertSignature("varchar", ImmutableList.<String>of());
        assertSignature("array", ImmutableList.of("bigint"));
        assertSignature("array", ImmutableList.of("array<bigint>"));
        assertSignature("map", ImmutableList.of("bigint", "bigint"));
        assertSignature("map", ImmutableList.of("bigint", "array<bigint>"));
        assertSignature("map", ImmutableList.of("bigint", "map<bigint,map<varchar,bigint>>"));
        assertSignature("array", ImmutableList.of("timestamp with time zone"));
        assertSignature("row", ImmutableList.of("bigint", "varchar"), ImmutableList.<Object>of("a", "b"));
        assertSignature("row", ImmutableList.of("bigint", "array<bigint>", "row<bigint>('a')"), ImmutableList.<Object>of("a", "b", "c"));
        assertSignature("row", ImmutableList.of("varchar(10)", "row<bigint>('a')"), ImmutableList.<Object>of("a", "b"));
        assertSignature("foo", ImmutableList.<String>of(), ImmutableList.<Object>of("a"));
        assertSignature("varchar", ImmutableList.<String>of(), ImmutableList.<Object>of(10L));
        try {
            parseTypeSignature("blah<>");
            fail("Type signatures with zero parameters should fail to parse");
        }
        catch (RuntimeException e) {
            // Expected
        }
        try {
            parseTypeSignature("blah()");
            fail("Type signatures with zero literal parameters should fail to parse");
        }
        catch (RuntimeException e) {
            // Expected
        }
    }

    private static void assertSignature(String base, List<String> parameters)
    {
        assertSignature(base, parameters, ImmutableList.of());
    }

    private static void assertSignature(String base, List<String> parameters, List<Object> literalParameters)
    {
        List<String> lowerCaseTypeNames = FluentIterable.from(parameters).transform(new Function<String, String>() {
            @Override
            public String apply(String input)
            {
                return input.toLowerCase(ENGLISH);
            }
        }).toList();

        String typeName = base.toLowerCase(ENGLISH);
        if (!parameters.isEmpty()) {
            typeName += "<" + Joiner.on(",").join(lowerCaseTypeNames) + ">";
        }
        if (!literalParameters.isEmpty()) {
            typeName += "(" + Joiner.on(",").join(Lists.transform(literalParameters, new Function<Object, String>() {
                @Override
                public String apply(Object input)
                {
                    if (input instanceof String) {
                        return "'" + input + "'";
                    }
                    else {
                        return input.toString();
                    }
                }
            })) + ")";
        }
        TypeSignature signature = parseTypeSignature(typeName);
        assertEquals(signature.getBase(), base);
        assertEquals(signature.getParameters().size(), parameters.size());
        for (int i = 0; i < signature.getParameters().size(); i++) {
            assertEquals(signature.getParameters().get(i).toString(), parameters.get(i));
        }
        assertEquals(signature.getLiteralParameters(), literalParameters);
        assertEquals(typeName, signature.toString());
    }
}

@@ -628,103 +628,14 @@
 ase.
-Function;%0Aimport com.google.common.base.Joiner;%0Aimport com.google.common.collect.FluentIterable
+Joiner
 ;%0Aim
@@ -684,48 +684,8 @@
 st;%0A
-import com.google.common.collect.Lists;%0A
 impo
@@ -818,16 +818,16 @@
 nature;%0A
-
 import s
@@ -858,16 +858,66 @@
 NGLISH;%0A
+import static java.util.stream.Collectors.toList;%0A
 import s
@@ -3053,193 +3053,63 @@
 s = 
-FluentIterable.from(parameters).transform(new Function%3CString, String%3E() %7B%0A            @Override%0A            public String apply(String input)%0A            %7B%0A                return input
+parameters.stream()%0A                .map(value -%3E value
 .toL
@@ -3117,33 +3117,33 @@
 werCase(ENGLISH)
-;
+)
 %0A            %7D%0A 
@@ -3141,31 +3141,31 @@
     
-  %7D%0A
       
-  %7D).
+.collect(
 toList()
 ;%0A%0A 
@@ -3160,16 +3160,17 @@
 toList()
+)
 ;%0A%0A     
@@ -3401,52 +3401,21 @@
     
-typeName += %22(%22 + Joiner.on(%22,%22).join(Lists.
+List%3CString%3E 
 tran
@@ -3419,17 +3419,19 @@
 ransform
-(
+ = 
 literalP
@@ -3443,390 +3443,179 @@
 ters
-, new Function%3CObject, String%3E() %7B%0A                @Override%0A                public String apply(Object input)%0A                %7B%0A                    if (input instanceof String) %7B%0A                        return %22'%22 + input + %22'%22;%0A                    %7D%0A                    else %7B%0A                        return input.toString();%0A                    %7D%0A                %7D%0A            %7D)
+.stream()%0A                    .map(TestTypeSignature::convertParameter)%0A                    .collect(toList());%0A            typeName += %22(%22 + Joiner.on(%22,%22).join(transform
 ) + 
@@ -4120,11 +4120,201 @@
 );%0A    %7D
+%0A%0A    private static String convertParameter(Object value)%0A    %7B%0A        if (value instanceof String) %7B%0A            return %22'%22 + value + %22'%22;%0A        %7D%0A        return value.toString();%0A    %7D
 %0A%7D%0A

Convert TestTypeSignature to streams