package io.cloudslang.lang.compiler.modeller.transformers;

import io.cloudslang.lang.compiler.SlangSource;
import io.cloudslang.lang.compiler.SlangTextualKeys;
import io.cloudslang.lang.compiler.parser.YamlParser;
import io.cloudslang.lang.compiler.parser.model.ParsedSlang;
import io.cloudslang.lang.entities.bindings.Argument;
import junit.framework.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.introspector.BeanAccess;

import java.io.File;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/*******************************************************************************
* (c) Copyright 2014 Hewlett-Packard Development Company, L.P.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Apache License v2.0 which accompany this distribution.
*
* The Apache License is available at
* http://www.apache.org/licenses/LICENSE-2.0
*
*******************************************************************************/


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = DoTransformerTest.Config.class)
public class DoTransformerTest {

    @Autowired
    private DoTransformer doTransformer;

    @Autowired
    private YamlParser yamlParser;

    @Rule
    public ExpectedException exception = ExpectedException.none();

    @Test
    public void testTransformExpression() throws Exception {
        LinkedHashMap doArgumentsMap = loadFirstTaskFromFile("/flow_with_data.yaml");
        @SuppressWarnings("unchecked") List<Argument> arguments = doTransformer.transform(doArgumentsMap);
        Assert.assertFalse(arguments.isEmpty());
        Assert.assertEquals(2, arguments.size());
        Argument argument = arguments.iterator().next();
        Assert.assertEquals("city",argument.getName());
        Assert.assertEquals("city_name", argument.getExpression());
    }

    @Test
    public void testTransformConst() throws Exception {
        LinkedHashMap doArgumentsMap = loadFirstTaskFromFile("/flow_with_data.yaml");
        @SuppressWarnings("unchecked") List<Argument> arguments = doTransformer.transform(doArgumentsMap);
        Assert.assertFalse(arguments.isEmpty());
        Assert.assertEquals(2, arguments.size());
        Argument argument = arguments.get(1);
        Assert.assertEquals("country", argument.getName());
        Assert.assertEquals("str('Israel')", argument.getExpression());
    }

    @Test
    public void testTransformEmptyArgumentExpression() throws Exception {
        exception.expect(RuntimeException.class);
        exception.expectMessage("country");
        exception.expectMessage("null");
        LinkedHashMap doArgumentsMap = loadFirstTaskFromFile("/corrupted/flow_with_empty_argument_expression.yaml");
        doTransformer.transform(doArgumentsMap);
    }

    @Test
    public void testTransformArgumentWithModifiers() throws Exception {
        exception.expect(RuntimeException.class);
        exception.expectMessage("country");
        exception.expectMessage("modifier");
        LinkedHashMap doArgumentsMap = loadFirstTaskFromFile("/corrupted/flow_with_argument_modifiers.yaml");
        doTransformer.transform(doArgumentsMap);
    }

    @Test
    public void testTransformInvalidArgument() throws Exception {
        exception.expect(RuntimeException.class);
        exception.expectMessage("argument");
        exception.expectMessage("22");
        LinkedHashMap doArgumentsMap = loadFirstTaskFromFile("/corrupted/flow_with_invalid_argument.yaml");
        doTransformer.transform(doArgumentsMap);
    }

    private LinkedHashMap loadFirstTaskFromFile(String path) throws URISyntaxException {
        LinkedHashMap doArgumentsMap = new LinkedHashMap();
        URL resource = getClass().getResource(path);
        File file = new File(resource.toURI());
        ParsedSlang parsedSlang = yamlParser.parse(SlangSource.fromFile(file));
        @SuppressWarnings("unchecked")
        List<Map<String, Map>> flow = (List<Map<String, Map>>) parsedSlang.getFlow().get(SlangTextualKeys.WORKFLOW_KEY);
        for(Map<String, Map> task : flow){
            if(task.keySet().iterator().next().equals("CheckWeather")){
                doArgumentsMap = (LinkedHashMap) task.values().iterator().next().get(SlangTextualKeys.DO_KEY);
                return doArgumentsMap;
            }
        }
        return doArgumentsMap;
    }

    @Configuration
    public static class Config {

        @Bean
        public Yaml yaml() {
            Yaml yaml = new Yaml();
            yaml.setBeanAccess(BeanAccess.FIELD);
            return yaml;
        }

        @Bean
        public YamlParser yamlParser() {
            return new YamlParser();
        }

        @Bean
        public DoTransformer inputTransformer() {
            return new DoTransformer();
        }

    }
}

@@ -1903,34 +1903,24 @@
 n %7B%0A        
-LinkedHash
 Map doArgume
@@ -2439,34 +2439,24 @@
 n %7B%0A        
-LinkedHash
 Map doArgume
@@ -3117,32 +3117,33 @@
 ge(%22null%22);%0A
+%0A
         
 LinkedHashMa
@@ -3126,37 +3126,80 @@
 );%0A%0A        
-LinkedHashMap
+@SuppressWarnings(%22unchecked%22)%0A        Map%3CString, List%3E
  doArguments
@@ -3274,32 +3274,33 @@
 ression.yaml%22);%0A
+%0A
         doTransf
@@ -3556,32 +3556,33 @@
 modifier%22);%0A
+%0A
         
 LinkedHashMa
@@ -3565,37 +3565,80 @@
 );%0A%0A        
-LinkedHashMap
+@SuppressWarnings(%22unchecked%22)%0A        Map%3CString, List%3E
  doArguments
@@ -3706,32 +3706,33 @@
 difiers.yaml%22);%0A
+%0A
         doTransf
@@ -3981,24 +3981,25 @@
 (%2222%22);%0A
+%0A
         
 LinkedHa
@@ -3986,37 +3986,80 @@
 );%0A%0A        
-LinkedHashMap
+@SuppressWarnings(%22unchecked%22)%0A        Map%3CString, List%3E
  doArguments
@@ -4125,32 +4125,33 @@
 rgument.yaml%22);%0A
+%0A
         doTransf
@@ -4202,26 +4202,16 @@
 private 
-LinkedHash
 Map load
@@ -4277,26 +4277,16 @@
         
-LinkedHash
 Map doAr
@@ -4809,26 +4809,16 @@
 sMap = (
-LinkedHash
 Map) tas

resolve warnings