// Copyright 2016 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/network/user_agent_string_factory.h"

#include <vector>

#include "base/string_util.h"
#include "base/stringprintf.h"
#include "cobalt/version.h"

#include "cobalt_build_id.h"  // NOLINT(build/include)

namespace cobalt {
namespace network {

namespace {

#if defined(COBALT_BUILD_TYPE_DEBUG)
const char kBuildConfiguration[] = "debug";
#elif defined(COBALT_BUILD_TYPE_DEVEL)
const char kBuildConfiguration[] = "devel";
#elif defined(COBALT_BUILD_TYPE_QA)
const char kBuildConfiguration[] = "qa";
#elif defined(COBALT_BUILD_TYPE_GOLD)
const char kBuildConfiguration[] = "gold";
#else
#error Unknown build configuration.
#endif

}  // namespace

std::string UserAgentStringFactory::CreateUserAgentString() {
  // Cobalt's user agent contains the following sections:
  //   Mozilla/5.0 (ChromiumStylePlatform)
  //   Cobalt/Version.BuildNumber-BuildConfiguration (unlike Gecko)
  //   Starboard/APIVersion,
  //   Device/FirmwareVersion (Brand, Model, ConnectionType)

  //   Mozilla/5.0 (ChromiumStylePlatform)
  std::string user_agent =
      base::StringPrintf("Mozilla/5.0 (%s)", CreatePlatformString().c_str());

  //   Cobalt/Version.BuildNumber-BuildConfiguration (unlike Gecko)
  base::StringAppendF(&user_agent, " Cobalt/%s.%s-%s (unlike Gecko)",
                      COBALT_VERSION, COBALT_BUILD_VERSION_NUMBER,
                      kBuildConfiguration);

  //   Starboard/APIVersion,
  if (!starboard_version_.empty()) {
    base::StringAppendF(&user_agent, " %s", starboard_version_.c_str());
  }

  //   Device/FirmwareVersion (Brand, Model, ConnectionType)
  if (youtube_tv_info_) {
    base::StringAppendF(
        &user_agent, ", %s_%s_%s/%s (%s, %s, %s)",
        youtube_tv_info_->network_operator.value_or("").c_str(),
        CreateDeviceTypeString().c_str(),
        youtube_tv_info_->chipset_model_number.value_or("").c_str(),
        youtube_tv_info_->firmware_version.value_or("").c_str(),
        youtube_tv_info_->brand.c_str(), youtube_tv_info_->model.c_str(),
        CreateConnectionTypeString().c_str());
  }

  if (!aux_field_.empty()) {
    user_agent.append(" ");
    user_agent.append(aux_field_);
  }
  return user_agent;
}

// Inserts semicolons between non-empty components of the platform.
std::string UserAgentStringFactory::CreatePlatformString() {
  std::string platform;
  if (!historic_platform_name_.empty()) {
    platform += historic_platform_name_;
    platform += "; ";
  }

  DCHECK(!os_name_and_version_.empty());
  platform += os_name_and_version_;

  if (!architecture_tokens_.empty()) {
    platform += "; ";
    platform += architecture_tokens_;
  }

  return platform;
}

std::string UserAgentStringFactory::CreateDeviceTypeString() {
  switch (youtube_tv_info_->device_type) {
    case YouTubeTVInfo::kBlueRayDiskPlayer:
      return "BDP";
    case YouTubeTVInfo::kGameConsole:
      return "GAME";
    case YouTubeTVInfo::kOverTheTopBox:
      return "OTT";
    case YouTubeTVInfo::kSetTopBox:
      return "STB";
    case YouTubeTVInfo::kTV:
      return "TV";
#if SB_API_VERSION >= 4
    case YouTubeTVInfo::kAndroidTV:
      return "ATV";
#endif  // SB_API_VERSION >= 4
    case YouTubeTVInfo::kInvalidDeviceType:
    default:
      NOTREACHED();
      return "";
  }
}

std::string UserAgentStringFactory::CreateConnectionTypeString() {
  if (youtube_tv_info_->connection_type) {
    switch (*youtube_tv_info_->connection_type) {
      case YouTubeTVInfo::kWiredConnection:
        return "Wired";
      case YouTubeTVInfo::kWirelessConnection:
        return "Wireless";
      default:
        NOTREACHED();
    }
  }

  return "";
}

}  // namespace network
}  // namespace cobalt
