/*
 * 
 * Copyright 2001-2004 The Ant-Contrib project
 *
 *  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 net.sf.antcontrib.cpptasks.gcc;
import java.io.File;
import java.util.Vector;

import net.sf.antcontrib.cpptasks.CUtil;
import net.sf.antcontrib.cpptasks.compiler.LinkType;
import net.sf.antcontrib.cpptasks.compiler.Linker;
import net.sf.antcontrib.cpptasks.compiler.Processor;
import net.sf.antcontrib.cpptasks.parser.CParser;
import net.sf.antcontrib.cpptasks.parser.FortranParser;
import net.sf.antcontrib.cpptasks.parser.Parser;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.types.Environment;
import net.sf.antcontrib.cpptasks.OptimizationEnum;

/**
 * Adapter for the GCC C/C++ compiler
 * 
 * @author Adam Murdoch
 */
public final class GccCCompiler extends GccCompatibleCCompiler {
    private final static String[] sourceExtensions = new String[]{".c", /* C */
            ".cc", /* C++ */
            ".cpp", /* C++ */
            ".cxx", /* C++ */
            ".c++", /* C++ */
            ".i", /* preprocessed C */
            ".ii", /* preprocessed C++ */
            ".f", /* FORTRAN */
            ".for", /* FORTRAN */
            ".m", /* Objective-C */
            ".mm", /* Objected-C++ */
            ".s" /* Assembly */
            };
    private final static String[] headerExtensions = new String[]{".h", ".hpp",
    ".inl"};
    private static final GccCCompiler cppInstance = new GccCCompiler("c++",
            sourceExtensions, headerExtensions, false,
            new GccCCompiler("c++", sourceExtensions, headerExtensions, true,
                    null, false, null), false, null);
    private static final GccCCompiler g77Instance = new GccCCompiler("g77",
            sourceExtensions, headerExtensions, false,
            new GccCCompiler("g77", sourceExtensions, headerExtensions, true,
                    null, false, null), false, null);
    private static final GccCCompiler gppInstance = new GccCCompiler("g++",
            sourceExtensions, headerExtensions, false,
            new GccCCompiler("g++", sourceExtensions, headerExtensions, true,
                    null, false, null), false, null);
    private static final GccCCompiler instance = new GccCCompiler("gcc",
            sourceExtensions, headerExtensions, false,
            new GccCCompiler("gcc", sourceExtensions, headerExtensions, true,
                    null, false, null), false, null);
    /**
     * Gets c++ adapter
     */
    public static GccCCompiler getCppInstance() {
        return cppInstance;
    }
    /**
     * Gets g77 adapter
     */
    public static GccCCompiler getG77Instance() {
        return g77Instance;
    }
    /**
     * Gets gpp adapter
     */
    public static GccCCompiler getGppInstance() {
        return gppInstance;
    }
    /**
     * Gets gcc adapter
     */
    public static GccCCompiler getInstance() {
        return instance;
    }
    private String identifier;
    private File[] includePath;
    private boolean isPICMeaningful = true;
    /**
     * Private constructor. Use GccCCompiler.getInstance() to get singleton
     * instance of this class.
     */
    private GccCCompiler(String command, String[] sourceExtensions,
            String[] headerExtensions, boolean isLibtool,
            GccCCompiler libtoolCompiler, boolean newEnvironment,
            Environment env) {
        super(command, null, sourceExtensions, headerExtensions, isLibtool,
                libtoolCompiler, newEnvironment, env);
        isPICMeaningful = System.getProperty("os.name").indexOf("Windows") < 0;
    }
    public void addImpliedArgs(final Vector args, 
    		final boolean debug,
            final boolean multithreaded, 
			final boolean exceptions, 
			final LinkType linkType,
			final Boolean rtti,
			final OptimizationEnum optimization,
   final Boolean defaultflag) {
        super.addImpliedArgs(args, debug, multithreaded, 
        		exceptions, linkType, rtti, optimization, defaultflag);
        if (isPICMeaningful && linkType.isSharedLibrary()) {
            args.addElement("-fPIC");
        }
    }
    public Processor changeEnvironment(boolean newEnvironment, Environment env) {
        if (newEnvironment || env != null) {
            return new GccCCompiler(getCommand(), this.getSourceExtensions(),
                    this.getHeaderExtensions(), this.getLibtool(),
                    (GccCCompiler) this.getLibtoolCompiler(), newEnvironment,
                    env);
        }
        return this;
    }
    /**
     * Create parser to determine dependencies.
     * 
     * Will create appropriate parser (C++, FORTRAN) based on file extension.
     *  
     */
    protected Parser createParser(File source) {
        if (source != null) {
            String sourceName = source.getName();
            int lastDot = sourceName.lastIndexOf('.');
            if (lastDot >= 0 && lastDot + 1 < sourceName.length()) {
                char afterDot = sourceName.charAt(lastDot + 1);
                if (afterDot == 'f' || afterDot == 'F') {
                    return new FortranParser();
                }
            }
        }
        return new CParser();
    }
    public File[] getEnvironmentIncludePath() {
        if (includePath == null) {
            //
            //   construct default include path from machine id and version id
            //
            String[] defaultInclude = new String[1];
            StringBuffer buf = new StringBuffer("/lib/");
            buf.append(GccProcessor.getMachine());
            buf.append('/');
            buf.append(GccProcessor.getVersion());
            buf.append("/include");
            defaultInclude[0] = buf.toString();
            //
            //   read specs file and look for -istart and -idirafter
            //
            String[] specs = GccProcessor.getSpecs();
            String[][] optionValues = GccProcessor.parseSpecs(specs, "*cpp:",
                    new String[]{"-isystem ", "-idirafter "});
            //
            //   if no entries were found, then use a default path
            //
            if (optionValues[0].length == 0 && optionValues[1].length == 0) {
                optionValues[0] = new String[]{"/usr/local/include",
                        "/usr/include", "/usr/include/win32api"};
            }
            //
            //  remove mingw entries.
            //    For MinGW compiles this will mean the
            //      location of the sys includes will be
            //      wrong in dependencies.xml
            //      but that should have no significant effect
            for (int i = 0; i < optionValues.length; i++) {
                for (int j = 0; j < optionValues[i].length; j++) {
                    if (optionValues[i][j].indexOf("mingw") > 0) {
                        optionValues[i][j] = null;
                    }
                }
            }
            //
            //   if cygwin then
            //     we have to prepend location of gcc32
            //       and .. to start of absolute filenames to
            //       have something that will exist in the
            //       windows filesystem
            if (GccProcessor.isCygwin()) {
                GccProcessor.convertCygwinFilenames(optionValues[0]);
                GccProcessor.convertCygwinFilenames(optionValues[1]);
                GccProcessor.convertCygwinFilenames(defaultInclude);
            }
            int count = CUtil.checkDirectoryArray(optionValues[0]);
            count += CUtil.checkDirectoryArray(optionValues[1]);
            count += CUtil.checkDirectoryArray(defaultInclude);
            includePath = new File[count];
            int index = 0;
            for (int i = 0; i < optionValues.length; i++) {
                for (int j = 0; j < optionValues[i].length; j++) {
                    if (optionValues[i][j] != null) {
                        includePath[index++] = new File(optionValues[i][j]);
                    }
                }
            }
            for (int i = 0; i < defaultInclude.length; i++) {
                if (defaultInclude[i] != null) {
                    includePath[index++] = new File(defaultInclude[i]);
                }
            }
        }
        return (File[]) includePath.clone();
    }
    public String getIdentifier() throws BuildException {
        if (identifier == null) {
            StringBuffer buf;
            if (getLibtool()) {
                buf = new StringBuffer("libtool ");
            } else {
                buf = new StringBuffer(' ');
            }
            buf.append(getCommand());
            buf.append(' ');
            buf.append(GccProcessor.getVersion());
            buf.append(' ');
            buf.append(GccProcessor.getMachine());
            identifier = buf.toString();
        }
        return identifier;
    }
    public Linker getLinker(LinkType linkType) {
        return GccLinker.getInstance().getLinker(linkType);
    }
    public int getMaximumCommandLength() {
        return Integer.MAX_VALUE;
    }
}
