// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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.

#include "cobalt/cssom/media_list.h"

#include "cobalt/cssom/media_query.h"
#include "cobalt/cssom/testing/mock_css_parser.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace cssom {

using ::testing::_;
using ::testing::Return;

TEST(MediaListTest, MediaTextSetter) {
  testing::MockCSSParser css_parser;
  scoped_refptr<MediaList> media_list(new MediaList(&css_parser));
  const std::string media_query = "screen, (width: 1024px)";

  scoped_refptr<MediaList> parsed_media_list(new MediaList(&css_parser));
  scoped_refptr<MediaQuery> media_query_1(new MediaQuery(true));
  scoped_refptr<MediaQuery> media_query_2(new MediaQuery(true));
  parsed_media_list->Append(media_query_1);
  parsed_media_list->Append(media_query_2);

  EXPECT_CALL(css_parser, ParseMediaList(media_query, _))
      .WillOnce(Return(parsed_media_list));
  media_list->set_media_text(media_query);
  EXPECT_EQ(2, media_list->length());
}

TEST(MediaListTest, ItemAccessAndLength) {
  testing::MockCSSParser css_parser;
  scoped_refptr<MediaList> media_list(new MediaList(&css_parser));
  EXPECT_EQ(0, media_list->length());
  EXPECT_TRUE(media_list->Item(0).empty());

  scoped_refptr<MediaQuery> media_query(new MediaQuery(true));
  media_list->Append(media_query);
  EXPECT_EQ(1, media_list->length());
  // The returned string is empty, because MediaQuery serialization is not
  // implemented yet.
  EXPECT_TRUE(media_list->Item(0).empty());
  EXPECT_TRUE(media_list->Item(1).empty());
}

TEST(MediaListTest, AppendMedium) {
  testing::MockCSSParser css_parser;
  scoped_refptr<MediaList> media_list(new MediaList(&css_parser));
  EXPECT_EQ(0, media_list->length());
  const std::string media_query = "screen";

  EXPECT_CALL(css_parser, ParseMediaQuery(media_query, _))
      .WillOnce(Return(scoped_refptr<MediaQuery>(new MediaQuery(true))));
  media_list->AppendMedium(media_query);
  EXPECT_EQ(1, media_list->length());
}

TEST(MediaListTest, EvaluateMediaQueryFalse) {
  scoped_refptr<MediaQuery> media_query(new MediaQuery(false));
  scoped_refptr<MediaList> media_list(new MediaList());

  media_list->Append(media_query);
  EXPECT_FALSE(media_list->EvaluateConditionValue(math::Size(0, 0)));
}

TEST(MediaListTest, EvaluateMediaQueryTrue) {
  scoped_refptr<MediaQuery> media_query(new MediaQuery(true));
  EXPECT_TRUE(media_query->EvaluateConditionValue(math::Size(0, 0)));

  scoped_refptr<MediaList> media_list(new MediaList());
  media_list->Append(media_query);
  EXPECT_TRUE(media_list->EvaluateConditionValue(math::Size(0, 0)));
}

TEST(MediaListTest, EvaluateMediaQueriesFalseAndFalse) {
  scoped_refptr<MediaQuery> media_query_1(new MediaQuery(false));
  EXPECT_FALSE(media_query_1->EvaluateConditionValue(math::Size(0, 0)));

  scoped_refptr<MediaQuery> media_query_2(new MediaQuery(false));
  EXPECT_FALSE(media_query_2->EvaluateConditionValue(math::Size(0, 0)));

  scoped_refptr<MediaList> media_list(new MediaList());
  media_list->Append(media_query_1);
  media_list->Append(media_query_2);
  EXPECT_FALSE(media_list->EvaluateConditionValue(math::Size(0, 0)));
}

TEST(MediaListTest, EvaluateMediaQueriesFalseAndTrue) {
  scoped_refptr<MediaQuery> media_query_1(new MediaQuery(false));
  EXPECT_FALSE(media_query_1->EvaluateConditionValue(math::Size(0, 0)));

  scoped_refptr<MediaQuery> media_query_2(new MediaQuery(true));
  EXPECT_TRUE(media_query_2->EvaluateConditionValue(math::Size(0, 0)));

  scoped_refptr<MediaList> media_list(new MediaList());
  media_list->Append(media_query_1);
  media_list->Append(media_query_2);
  EXPECT_TRUE(media_list->EvaluateConditionValue(math::Size(0, 0)));
}

TEST(MediaListTest, EvaluateMediaQueriesTrueAndFalse) {
  scoped_refptr<MediaQuery> media_query_1(new MediaQuery(true));
  EXPECT_TRUE(media_query_1->EvaluateConditionValue(math::Size(0, 0)));

  scoped_refptr<MediaQuery> media_query_2(new MediaQuery(false));
  EXPECT_FALSE(media_query_2->EvaluateConditionValue(math::Size(0, 0)));

  scoped_refptr<MediaList> media_list(new MediaList());
  media_list->Append(media_query_1);
  media_list->Append(media_query_2);
  EXPECT_TRUE(media_list->EvaluateConditionValue(math::Size(0, 0)));
}

TEST(MediaListTest, EvaluateMediaQueriesTrueAndTrue) {
  scoped_refptr<MediaQuery> media_query_1(new MediaQuery(true));
  EXPECT_TRUE(media_query_1->EvaluateConditionValue(math::Size(0, 0)));

  scoped_refptr<MediaQuery> media_query_2(new MediaQuery(true));
  EXPECT_TRUE(media_query_2->EvaluateConditionValue(math::Size(0, 0)));

  scoped_refptr<MediaList> media_list(new MediaList());
  media_list->Append(media_query_1);
  media_list->Append(media_query_2);
  EXPECT_TRUE(media_list->EvaluateConditionValue(math::Size(0, 0)));
}

}  // namespace cssom
}  // namespace cobalt
