/* disabled jul21 because ReSample can no longer be copied around
   anyway, too complicated, needs to be radically simplified

#include "Base/Const/Units.h"
#include "Resample/Processed/ReSample.h"
#include "Resample/Slice/KzComputation.h"
#include "Resample/Specular/SpecularScalarTanhStrategy.h"
#include "Resample/Specular/TransitionMagneticTanh.h"
#include "Sample/Material/MaterialFactoryFuncs.h"
#include "Sample/Multilayer/Layer.h"
#include "Sample/Multilayer/MultiLayer.h"
#include "Tests/GTestWrapper/google_test.h"
#include <utility>

class SpecularMagneticTest : public ::testing::Test {
protected:
    auto static constexpr eps = 1.e-10;

    std::unique_ptr<const ReSample> sample_zerofield(bool slab);
    std::unique_ptr<const ReSample> sample_degenerate();

    template <typename Strategy> void test_degenerate();
    template <typename Strategy>
    void testZeroField(const R3& k, const ReSample& sample);
    template <typename Strategy>
    void testcase_zerofield(std::vector<double>&& angles, bool slab = false);
};

template <> void SpecularMagneticTest::test_degenerate<SpecularMagneticTanhStrategy>()
{
    R3 v;

    Spinor T1p{0.0, 0.0};
    Spinor T2p{1.0, 0.0};
    Spinor R1p{0.0, 0.0};
    Spinor R2p{0.0, 0.0};
    Spinor T1m{0.0, 1.0};
    Spinor T2m{0.0, 0.0};
    Spinor R1m{0.0, 0.0};
    Spinor R2m{0.0, 0.0};

    auto sample = sample_degenerate();
    auto result =
        std::make_unique<SpecularMagneticTanhStrategy>()->Execute(sample->averageSlices(), v);
    for (auto& coeff : result) {
        EXPECT_NEAR_VECTOR2CD(coeff->T1plus(), T1p, eps);
        EXPECT_NEAR_VECTOR2CD(coeff->T2plus(), T2p, eps);
        EXPECT_NEAR_VECTOR2CD(coeff->T1min(), T1m, eps);
        EXPECT_NEAR_VECTOR2CD(coeff->T2min(), T2m, eps);
        EXPECT_NEAR_VECTOR2CD(coeff->R1plus(), R1p, eps);
        EXPECT_NEAR_VECTOR2CD(coeff->R2plus(), R2p, eps);
        EXPECT_NEAR_VECTOR2CD(coeff->R1min(), R1m, eps);
        EXPECT_NEAR_VECTOR2CD(coeff->R2min(), R2m, eps);
    }
}

//! Compares results with scalar case
template <typename Strategy>
void SpecularMagneticTest::testZeroField(const R3& k, const ReSample& sample)
{
    const SliceStack& slices = sample.averageSlices();
    auto coeffs_scalar = std::make_unique<SpecularScalarTanhStrategy>()->Execute(
        slices, Compute::Kz::computeKzFromRefIndices(slices, k));
    auto coeffs_zerofield = std::make_unique<Strategy>()->Execute(
        slices, Compute::Kz::computeKzFromRefIndices(slices, k));

    EXPECT_EQ(coeffs_scalar.size(), coeffs_zerofield.size());

    for (size_t i = 0; i < coeffs_scalar.size(); ++i) {
        auto* RTScalar = coeffs_scalar[i].get();
        auto* RTMatrix = coeffs_zerofield[i].get();

        EXPECT_NEAR_VECTOR2CD(RTMatrix->T1plus(), RTScalar->T1plus(), eps);
        EXPECT_NEAR_VECTOR2CD(RTMatrix->T2plus(), RTScalar->T2plus(), eps);
        EXPECT_NEAR_VECTOR2CD(RTMatrix->R1plus(), RTScalar->R1plus(), eps);
        EXPECT_NEAR_VECTOR2CD(RTMatrix->R2plus(), RTScalar->R2plus(), eps);

        EXPECT_NEAR_VECTOR2CD(RTMatrix->T1min(), RTScalar->T1min(), eps);
        EXPECT_NEAR_VECTOR2CD(RTMatrix->T2min(), RTScalar->T2min(), eps);
        EXPECT_NEAR_VECTOR2CD(RTMatrix->R1min(), RTScalar->R1min(), eps);
        EXPECT_NEAR_VECTOR2CD(RTMatrix->R2min(), RTScalar->R2min(), eps);

        EXPECT_NEAR_VECTOR2CD(RTMatrix->getKz(), RTScalar->getKz(), eps);
    }
}

std::unique_ptr<const ReSample> SpecularMagneticTest::sample_degenerate()
{
    MultiLayer mLayer;
    Material air = RefractiveMaterial("Vacuum", 0, 1.0);
    mLayer.addLayer(Layer(air, 0 * Units::nm));
    return std::make_unique<ReSample>(ReSample::make(mLayer));
}

TEST_F(SpecularMagneticTest, degenerate_)
{
    test_degenerate<SpecularMagneticTanhStrategy>();
}

std::unique_ptr<const ReSample> SpecularMagneticTest::sample_zerofield(bool slab)
{
    MultiLayer sample_scalar;
    Material substr_material_scalar = RefractiveMaterial("Substrate", 7e-6, 2e-8);
    Layer vacuum_layer(RefractiveMaterial("Vacuum", 0.0, 0.0));
    Layer substr_layer_scalar(substr_material_scalar);
    sample_scalar.addLayer(vacuum_layer);

    if (slab) {
        Material layer_material = RefractiveMaterial("Layer", 3e-6, 1e-8);
        Layer layer(layer_material, 10. * Units::nm);
        sample_scalar.addLayer(layer);
    }

    sample_scalar.addLayer(substr_layer_scalar);

    return std::make_unique<ReSample>(ReSample::make(sample_scalar));
}

template <typename Strategy>
void SpecularMagneticTest::testcase_zerofield(std::vector<double>&& angles, bool slab)
{
    for (auto& angle : angles) {
        auto sample = sample_zerofield(slab);
        R3 k = vecOfLambdaAlphaPhi(1.0, angle * Units::deg, 0.0);
        testZeroField<Strategy>(k, *sample);
    }
}

TEST_F(SpecularMagneticTest, zerofield_positive_k)
{
    testcase_zerofield<SpecularMagneticTanhStrategy>({0.0, 1.e-9, 1.e-5, 0.1, 2.0, 10.0});
}

TEST_F(SpecularMagneticTest, zerofield_negative_k)
{
    testcase_zerofield<SpecularMagneticTanhStrategy>({-0.0, -1.e-9, -1.e-5, -0.1, -2.0, -10.0});
}

TEST_F(SpecularMagneticTest, zerofield2_positive_k)
{
    testcase_zerofield<SpecularMagneticTanhStrategy>({0.0, 1.e-9, 1.e-5, 0.1, 2.0, 10.0}, true);
}

TEST_F(SpecularMagneticTest, zerofield2_negative_k)
{
    testcase_zerofield<SpecularMagneticTanhStrategy>({-0.0, -1.e-9, -1.e-5, -0.1, -2.0, -10.0},
                                                     true);
}

*/
