﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OfficeOpenXml.FormulaParsing;
using Rhino.Mocks;
using ExGraph = OfficeOpenXml.FormulaParsing.ExpressionGraph.ExpressionGraph;
using OfficeOpenXml.FormulaParsing.LexicalAnalysis;
using OfficeOpenXml.FormulaParsing.ExpressionGraph;

namespace EPPlusTest.FormulaParsing
{
    [TestClass]
    public class FormulaParserTests
    {
        private FormulaParser _parser;

        [TestInitialize]
        public void Setup()
        {
            var provider = MockRepository.GenerateStub<ExcelDataProvider>();
            _parser = new FormulaParser(provider);

        }

        [TestCleanup]
        public void Cleanup()
        {

        }

        [TestMethod]
        public void ParserShouldCallLexer()
        {
            var lexer = MockRepository.GenerateStub<ILexer>();
            lexer.Stub(x => x.Tokenize("ABC")).Return(Enumerable.Empty<Token>());
            _parser.Configure(x => x.SetLexer(lexer));

            _parser.Parse("ABC");

            lexer.AssertWasCalled(x => x.Tokenize("ABC"));
        }

        [TestMethod]
        public void ParserShouldCallGraphBuilder()
        {
            var lexer = MockRepository.GenerateStub<ILexer>();
            var tokens = new List<Token>();
            lexer.Stub(x => x.Tokenize("ABC")).Return(tokens);
            var graphBuilder = MockRepository.GenerateStub<IExpressionGraphBuilder>();
            graphBuilder.Stub(x => x.Build(tokens)).Return(new ExGraph());

            _parser.Configure(config =>
                {
                    config
                        .SetLexer(lexer)
                        .SetGraphBuilder(graphBuilder);
                });

            _parser.Parse("ABC");

            graphBuilder.AssertWasCalled(x => x.Build(tokens));
        }

        [TestMethod]
        public void ParserShouldCallCompiler()
        {
            var lexer = MockRepository.GenerateStub<ILexer>();
            var tokens = new List<Token>();
            lexer.Stub(x => x.Tokenize("ABC")).Return(tokens);
            var expectedGraph = new ExGraph();
            expectedGraph.Add(new StringExpression("asdf"));
            var graphBuilder = MockRepository.GenerateStub<IExpressionGraphBuilder>();
            graphBuilder.Stub(x => x.Build(tokens)).Return(expectedGraph);
            var compiler = MockRepository.GenerateStub<IExpressionCompiler>();
            compiler.Stub(x => x.Compile(expectedGraph.Expressions)).Return(new CompileResult(0, DataType.Integer));

            _parser.Configure(config =>
            {
                config
                    .SetLexer(lexer)
                    .SetGraphBuilder(graphBuilder)
                    .SetExpresionCompiler(compiler);
            });

            _parser.Parse("ABC");

            compiler.AssertWasCalled(x => x.Compile(expectedGraph.Expressions));
        }

        [TestMethod]
        public void ParseAtShouldCallExcelDataProvider()
        {
            var excelDataProvider = MockRepository.GenerateStub<ExcelDataProvider>();
            excelDataProvider
                .Stub(x => x.GetRangeFormula(string.Empty, 1, 1))
                .Return("Sum(1,2)");
            var parser = new FormulaParser(excelDataProvider);
            var result = parser.ParseAt("A1");
            Assert.AreEqual(3d, result);
        }

        [TestMethod, ExpectedException(typeof(ArgumentException))]
        public void ParseAtShouldThrowIfAddressIsNull()
        {
            _parser.ParseAt(null);
        }
    }
}
