// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.IO;

namespace NaCl.Build.CPPTasks
{
    /// <summary>
    /// Parser for the dependancy files generated by gcc (.d files).
    /// This is not a general purpose .d file parser.  In particular it
    /// assumes exactly one dependancy per line.
    /// </summary>
    public class DependencyParser
    {
        private List<string> m_dependencies = new List<string>();

        public List<String> Dependencies
        {
            get
            {
                return m_dependencies;
            }
        }

        public DependencyParser()
        {
        }

        public DependencyParser(string filename)
        {
            using (StreamReader reader = new StreamReader(filename, Encoding.ASCII))
            {
                Parse(reader);
            }
        }

        public void Parse(string content)
        {
            Parse(new StringReader(content));
        }

        public void Parse(TextReader reader)
        {
            while (true)
            {
                string str = reader.ReadLine();
                if (str == null)
                    break;
                ParseLine(str);
            }
            reader.Close();
        }

        private void AddDependency(string filename)
        {
            filename = GCCUtilities.ConvertPathPosixToWindows(filename);
            filename = filename.Replace("\\ ", " ");
            m_dependencies.Add(filename);
        }

        /// <summary>
        /// Find the end of the current filename on the given line from a dependancy file.
        /// Normally this is the space char but, spaces can be escaped with backslash and
        /// end of string could also terminate the filename.
        /// </summary>
        private static int FindEndOfFilename(string line)
        {
            bool escapeSpace = false;
            int i = 0;
            for (i = 0; i < line.Length; i++)
            {
                if (line.ElementAt(i) == '\\')
                {
                    escapeSpace = true;
                }
                else if (line.ElementAt(i) == ' ' && !escapeSpace)
                {
                    // we found an unescaped space which represents the
                    // end of the current filename.
                    break;
                }
                else if (escapeSpace)
                {
                    escapeSpace = false;
                }
            }
            return i;
        }

        /// <summary>
        /// Parse a single line from a dependancy file.
        /// </summary>
        private void ParseLine(string line)
        {
            // Strip any trailing line continuation character.  Most lines of a gcc
            // generated .d files end with this char
            if (line.ElementAt(line.Length - 1) == '\\')
                line = line.Substring(0, line.Length - 1);

            if (m_dependencies.Count == 0)
            {
                // The first line of the .d files is <target>: <first_dep>.
                // For this line we want to strip the <target>: part.
                line = line.Split(new[] { ':' }, 2)[1];
            }

            // trim trailing whitespace
            line = line.Trim();

            // Now iterate through the line which can contain zero or more dependencies.
            // Although they are seperated by spaces we can't use Split() here since filenames
            // can also contain spaces that are escaped using backslash.  For some reason only
            // spaces are escaped.  Even literal backslash chars don't need escaping.
            while (line.Length != 0)
            {
                int end = FindEndOfFilename(line);
                AddDependency(line.Substring(0, end));
                if (end == line.Length)
                    break;
                line = line.Substring(end + 1).Trim();
            }
        }
    }
}
