#include "ui_core/layout_value.h"
#include "test_harness.h"

#include <string_view>

using pp::foundation::StatusCode;
using pp::ui::LayoutLengthKind;
using pp::ui::layout_length_kind_name;
using pp::ui::parse_layout_length;

namespace {

void parses_auto_pixels_and_percent(pp::tests::Harness& h)
{
    const auto auto_value = parse_layout_length("auto");
    const auto pixels = parse_layout_length("28");
    const auto percent = parse_layout_length("100%");

    PP_EXPECT(h, auto_value.ok());
    PP_EXPECT(h, auto_value.value().kind == LayoutLengthKind::auto_value);
    PP_EXPECT(h, pixels.ok());
    PP_EXPECT(h, pixels.value().kind == LayoutLengthKind::pixels);
    PP_EXPECT(h, pixels.value().value == 28U);
    PP_EXPECT(h, percent.ok());
    PP_EXPECT(h, percent.value().kind == LayoutLengthKind::percent);
    PP_EXPECT(h, percent.value().value == 100U);
    PP_EXPECT(h, layout_length_kind_name(LayoutLengthKind::percent) == std::string_view("percent"));
}

void rejects_invalid_layout_lengths(pp::tests::Harness& h)
{
    const auto empty = parse_layout_length("");
    const auto negative = parse_layout_length("-1");
    const auto trailing = parse_layout_length("28px");
    const auto too_large_percent = parse_layout_length("101%");
    const auto bare_percent = parse_layout_length("%");

    PP_EXPECT(h, !empty.ok());
    PP_EXPECT(h, empty.status().code == StatusCode::invalid_argument);
    PP_EXPECT(h, !negative.ok());
    PP_EXPECT(h, negative.status().code == StatusCode::invalid_argument);
    PP_EXPECT(h, !trailing.ok());
    PP_EXPECT(h, trailing.status().code == StatusCode::invalid_argument);
    PP_EXPECT(h, !too_large_percent.ok());
    PP_EXPECT(h, too_large_percent.status().code == StatusCode::out_of_range);
    PP_EXPECT(h, !bare_percent.ok());
    PP_EXPECT(h, bare_percent.status().code == StatusCode::invalid_argument);
}

}

int main()
{
    pp::tests::Harness harness;
    harness.run("parses_auto_pixels_and_percent", parses_auto_pixels_and_percent);
    harness.run("rejects_invalid_layout_lengths", rejects_invalid_layout_lengths);
    return harness.finish();
}
