// Copyright Naked Objects Group Ltd, 45 Station Road, Henley on Thames, UK, RG9 1AT
// 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.

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.ComponentModel;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NakedFramework.Architecture.Component;
using NakedFramework.Architecture.Facet;
using NakedFramework.Architecture.Reflect;
using NakedFramework.Architecture.Spec;
using NakedFramework.Architecture.SpecImmutable;
using NakedFramework.Metamodel.Facet;
using NakedObjects.Reflector.FacetFactory;

namespace NakedObjects.Reflector.Test.FacetFactory;

[TestClass]
public class ActionDefaultAnnotationFacetFactoryTest : AbstractFacetFactoryTest {
    private ActionDefaultAnnotationFacetFactory facetFactory;

    protected override Type[] SupportedTypes {
        get { return new[] { typeof(IActionDefaultsFacet) }; }
    }

    protected override IFacetFactory FacetFactory => facetFactory;

    [TestMethod]
    public override void TestFeatureTypes() {
        var featureTypes = facetFactory.FeatureTypes;
        Assert.IsFalse(featureTypes.HasFlag(FeatureType.Objects));
        Assert.IsFalse(featureTypes.HasFlag(FeatureType.Properties));
        Assert.IsFalse(featureTypes.HasFlag(FeatureType.Collections));
        Assert.IsFalse(featureTypes.HasFlag(FeatureType.Actions));
        Assert.IsTrue(featureTypes.HasFlag(FeatureType.ActionParameters));
    }

    [TestMethod]
    public void TestPropertyDefaultAnnotationPickedUpOnActionParameter() {
        IImmutableDictionary<string, ITypeSpecBuilder> metamodel = new Dictionary<string, ITypeSpecBuilder>().ToImmutableDictionary();
        var method = FindMethod(typeof(Customer2), "SomeAction", new[] { typeof(int) });
        metamodel = facetFactory.ProcessParams(Reflector, method, 0, Specification, metamodel);
        var facet = Specification.GetFacet(typeof(IActionDefaultsFacet));
        Assert.IsNotNull(facet);
        Assert.IsTrue(facet is ActionDefaultsFacetAnnotation);
        var actionDefaultFacetAnnotation = (ActionDefaultsFacetAnnotation)facet;
        Assert.AreEqual(1, actionDefaultFacetAnnotation.GetDefault(null, null).value);
        Assert.AreEqual(TypeOfDefaultValue.Explicit, actionDefaultFacetAnnotation.GetDefault(null, null).type);
        Assert.AreEqual(0, metamodel.Count);
    }

    #region Nested type: Customer2

    private class Customer2 {
        // ReSharper disable once UnusedMember.Local
        // ReSharper disable once UnusedParameter.Local
        public void SomeAction([DefaultValue(1)] int foo) { }
    }

    #endregion

    #region Setup/Teardown

    [TestInitialize]
    public override void SetUp() {
        base.SetUp();
        facetFactory = new ActionDefaultAnnotationFacetFactory(GetOrder<ActionDefaultAnnotationFacetFactory>(), LoggerFactory);
    }

    [TestCleanup]
    public override void TearDown() {
        facetFactory = null;
        base.TearDown();
    }

    #endregion
}

// Copyright (c) Naked Objects Group Ltd.