/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.royale.compiler.tools.annotate;

import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

public class OrderSwitches
{
    public static void processFile(File file) throws AnnotateClass.AnnotateClassDeleteException, AnnotateClass.AnnotateClassRenameException {
        if(!file.exists()) {
            System.out.println("Missing file: " + file.getPath());
            return;
        }
        try
        {
            // Prepare to read the file.
            FileInputStream fileInputStream = new FileInputStream(file);
            InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

            File tmpOutputFile = new File(file.getParentFile(), file.getName() + ".tmp");
            FileOutputStream fileOutputStream = new FileOutputStream(tmpOutputFile);
            PrintStream outputStream = new PrintStream(fileOutputStream);
            try
            {
                // Read it line-by-line.
                String line;
                ArrayList<String> lines = new ArrayList<String>();
                boolean inSwitch = false;
                while ((line = bufferedReader.readLine()) != null)
                {
                    if (line.contains("The following code was generated by JFlex "))
                    {
                    	int c = line.indexOf(" on ");
                    	if (c != -1)
                    		line = line.substring(0, c) + " */";
                    }
                    if (line.contains("* on ") && line.contains("from the specification file"))
                    	line = " * from the specification file";
                    if (line.contains("<tt>") && line.contains("compiler/src/main/jflex"))
                    {
                    	int t = line.indexOf("<tt>");
                    	int rc = line.indexOf("compiler/src/main/jflex");
                    	line = line.substring(0, t + 4) + line.substring(rc);
                    }
                    // If the line starts with "switch", and the cases are numbers, make sure they are in order.
                    if (line.contains("      switch (zzAction")) {
                    	inSwitch = true;
                        System.out.println("Ordering Switch in file: " + file.getPath());
                    }
                    if (inSwitch)
                    {
                    	lines.add(line);
                        if (line.startsWith("      }")) {
                        	orderSwitch(lines);
                        	for (String orderedLine : lines)
                        	{
                        		outputStream.println(orderedLine);
                        	}
                        	inSwitch = false;
                        }
                    }
                    else
                    	outputStream.println(line);
                }
            }
            finally
            {
                try {
                    bufferedReader.close();
                } catch(Exception e) {
                    // Ignore.
                }
                try {
                    outputStream.close();
                } catch(Exception e) {
                    // Ignore.
                }
                try {
                    fileOutputStream.close();
                } catch(Exception e) {
                    // Ignore.
                }
                try {
                    inputStreamReader.close();
                } catch(Exception e) {
                    // Ignore.
                }
                try {
                    fileInputStream.close();
                } catch(Exception e) {
                    // Ignore.
                }
            }

            // Remove the original file.
            if(!file.delete()) {
                // wait a bit then retry on Windows
                if (file.exists())
                {
                    for (int i = 0; i < 6; i++)
                    {
                        Thread.sleep(500);
                        System.gc();
                        if (file.delete())
                           break;
                    }
                    if (file.exists())
                        throw new AnnotateClass.AnnotateClassDeleteException("Error deleting original file at: " + file.getPath());
                }
            }

            // Rename the temp file to the name of the original file.
            if(!tmpOutputFile.renameTo(file)) {
                throw new AnnotateClass.AnnotateClassRenameException("Error renaming the temp file from: " + tmpOutputFile.getPath() +
                        " to: " + file.getPath());
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
    
    private static void orderSwitch(ArrayList<String> lines) {
    	HashMap<String,List<String>> switchMap = new HashMap<String,List<String>>();
    	ArrayList<String> defaultCase = new ArrayList<String>();
    	ArrayList<String> breaks = new ArrayList<String>();
    	String line0 = lines.get(0); // first line should be switch statement
    	boolean inDefault = false;
    	int n = lines.size();
    	for (int i = 1; i < n; i++)
    	{
    		String line = lines.get(i);
    		int c = line.indexOf(" case ");
    		if (!inDefault && (c != -1))
    		{
    			String cayse = line.substring(c);
    			if (line.contains("break;"))
    			{
    				// some cases just contain a break statement.
    				// the are used to make sure the prior case
    				// ends with a break without having to check
    				// if the break statement would be reachable
    				// due to return statements in the case.
    				breaks.add(line);
    				continue;
    			}
    			else
    			{
    				ArrayList<String> caseLines = new ArrayList<String>();
    				for (int j = i + 1; j < n; j++)
    				{
    					line = lines.get(j);
    					if (line.contains(" case "))
    					{
    						switchMap.put(cayse, caseLines);
    						i = j - 1;
    						break;
    					}
    					else if (line.contains("default:"))
    					{
    						switchMap.put(cayse, caseLines);
    						inDefault = true;
    						i = j;
    						// assumes no break at end of default case
    						defaultCase.add(line);
    						break;    						
    					}
    					caseLines.add(line);
    				}
    			}
    		}
			else if (line.contains("default:"))
			{
				inDefault = true;
				// assumes no break at end of default case
				defaultCase.add(line);
			}
    		else if (inDefault)
    			defaultCase.add(line);
    	}
    	Set<String> keys = switchMap.keySet();
    	ArrayList<String> keyList = new ArrayList<String>();
    	keyList.addAll(keys);
    	Collections.sort(keyList);
    	lines.clear();
    	lines.add(line0);
    	int breakIndex = 0;
    	for (String key : keyList)
    	{
    		lines.add("       " + key);
    		List<String> caseLines = switchMap.get(key);
    		lines.addAll(caseLines);
    		lines.add(breaks.get(breakIndex++));    		
    	}
    	boolean inSwitch = false;
    	boolean sawDefault = false;
    	ArrayList<String> switchLines = new ArrayList<String>();
    	for (String defaultLine : defaultCase)
    	{
            // If the line starts with "switch", and the cases are numbers, make sure they are in order.
            if (defaultLine.contains("switch (zzLexicalState)")) {
            	inSwitch = true;
                System.out.println("Ordering Switch in default: ");
            }
            if (inSwitch)
            {
            	switchLines.add(defaultLine);
            	if (defaultLine.contains("default:"))
            		sawDefault = true;
                if (sawDefault && defaultLine.startsWith("            }")) {
                	orderSwitch(switchLines);
                	for (String orderedLine : switchLines)
                	{
                		lines.add(orderedLine);
                	}
                	inSwitch = false;
                }
            }
            else
            	lines.add(defaultLine);

    	}
    	
    }
    
    public static void main(String[] args)
    {
        File f = new File(args[0]);
        try {
            processFile(f);
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }
}
