<commit_before>/******************************************************************************
 * Copyright 2018 The Apollo Authors. 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 "modules/dreamview/backend/hmi/hmi_worker.h"

#include "modules/common/adapters/adapter_gflags.h"
#include "modules/common/configs/config_gflags.h"
#include "modules/common/kv_db/kv_db.h"
#include "modules/common/util/file.h"
#include "modules/common/util/map_util.h"
#include "modules/common/util/message_util.h"
#include "modules/common/util/string_tokenizer.h"
#include "modules/common/util/string_util.h"
#include "modules/dreamview/backend/common/dreamview_gflags.h"
#include "modules/dreamview/backend/hmi/vehicle_manager.h"
#include "modules/monitor/proto/system_status.pb.h"

DEFINE_string(hmi_modes_config_path, "/apollo/modules/dreamview/conf/hmi_modes",
              "HMI modes config path.");

DEFINE_string(maps_data_path, "/apollo/modules/map/data", "Maps data path.");

DEFINE_string(vehicles_config_path, "/apollo/modules/calibration/data",
              "Vehicles config path.");

DEFINE_double(status_publish_interval, 5, "HMI Status publish interval.");

DEFINE_string(current_mode_db_key, "/apollo/hmi/status:current_mode",
              "Key to store hmi_status.current_mode in KV DB.");

DEFINE_string(default_hmi_mode, "Mkz Standard Debug",
              "Default HMI Mode when there is no cache.");

DEFINE_string(container_meta_ini, "/apollo/meta.ini",
              "Container meta info file.");

namespace apollo {
namespace dreamview {
namespace {

using apollo::canbus::Chassis;
using apollo::common::DriveEvent;
using apollo::common::KVDB;
using apollo::common::time::Clock;
using apollo::common::util::StrAppend;
using apollo::common::util::StrCat;
using apollo::control::DrivingAction;
using apollo::cyber::Node;
using apollo::monitor::ComponentStatus;
using apollo::monitor::SystemStatus;
using google::protobuf::Map;
using RLock = boost::shared_lock<boost::shared_mutex>;
using WLock = boost::unique_lock<boost::shared_mutex>;

constexpr char kNavigationModeName[] = "Navigation";

// Convert a string to be title-like. E.g.: "hello_world" -> "Hello World".
std::string TitleCase(const std::string& origin) {
  static const std::string kDelimiter = "_";
  std::vector<std::string> parts =
      apollo::common::util::StringTokenizer::Split(origin, kDelimiter);
  for (auto& part : parts) {
    if (!part.empty()) {
      // Upper case the first char.
      part[0] = static_cast<char>(toupper(part[0]));
    }
  }

  return apollo::common::util::PrintIter(parts);
}

// List subdirs and return a dict of {subdir_title: subdir_path}.
Map<std::string, std::string> ListDirAsDict(const std::string& dir) {
  Map<std::string, std::string> result;
  const auto subdirs = apollo::common::util::ListSubPaths(dir);
  for (const auto& subdir : subdirs) {
    const auto subdir_title = TitleCase(subdir);
    const auto subdir_path = StrCat(dir, "/", subdir);
    result.insert({subdir_title, subdir_path});
  }
  return result;
}

// List files by pattern and return a dict of {file_title: file_path}.
Map<std::string, std::string> ListFilesAsDict(const std::string& dir,
                                              const std::string& extension) {
  Map<std::string, std::string> result;
  const std::string pattern = StrCat(dir, "/*", extension);
  for (const std::string& file_path : apollo::common::util::Glob(pattern)) {
    // Remove the extention and convert to title case as the file title.
    const std::string filename = apollo::common::util::GetFileName(file_path);
    const std::string file_title =
        TitleCase(filename.substr(0, filename.length() - extension.length()));
    result.insert({file_title, file_path});
  }
  return result;
}

template <class FlagType, class ValueType>
void SetGlobalFlag(const std::string& flag_name, const ValueType& value,
                   FlagType* flag) {
  static constexpr char kGlobalFlagfile[] =
      "/apollo/modules/common/data/global_flagfile.txt";
  if (*flag != value) {
    *flag = value;
    // Overwrite global flagfile.
    std::ofstream fout(kGlobalFlagfile, std::ios_base::app);
    CHECK(fout) << "Fail to open global flagfile " << kGlobalFlagfile;
    fout << "\n--" << flag_name << "=" << value << std::endl;
  }
}

void System(const std::string& cmd) {
  const int ret = std::system(cmd.c_str());
  if (ret == 0) {
    AINFO << "SUCCESS: " << cmd;
  } else {
    AERROR << "FAILED(" << ret << "): " << cmd;
  }
}

std::string GetDockerImage() {
  const char* docker_image = std::getenv("DOCKER_IMG");
  return docker_image != nullptr ? docker_image : "";
}

}  // namespace

HMIWorker::HMIWorker(const std::shared_ptr<Node>& node)
    : config_(LoadConfig()), node_(node) {
  InitStatus();
}

void HMIWorker::Start() {
  InitReadersAndWriters();
  RegisterStatusUpdateHandler(
      [this](const bool status_changed, HMIStatus* status) {
        apollo::common::util::FillHeader("HMI", status);
        status_writer_->Write(*status);
        status->clear_header();<commit_msg>dreamview: fix return type of GetDockerName method<commit_after>/******************************************************************************
 * Copyright 2018 The Apollo Authors. 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 "modules/dreamview/backend/hmi/hmi_worker.h"

#include "modules/common/adapters/adapter_gflags.h"
#include "modules/common/configs/config_gflags.h"
#include "modules/common/kv_db/kv_db.h"
#include "modules/common/util/file.h"
#include "modules/common/util/map_util.h"
#include "modules/common/util/message_util.h"
#include "modules/common/util/string_tokenizer.h"
#include "modules/common/util/string_util.h"
#include "modules/dreamview/backend/common/dreamview_gflags.h"
#include "modules/dreamview/backend/hmi/vehicle_manager.h"
#include "modules/monitor/proto/system_status.pb.h"

DEFINE_string(hmi_modes_config_path, "/apollo/modules/dreamview/conf/hmi_modes",
              "HMI modes config path.");

DEFINE_string(maps_data_path, "/apollo/modules/map/data", "Maps data path.");

DEFINE_string(vehicles_config_path, "/apollo/modules/calibration/data",
              "Vehicles config path.");

DEFINE_double(status_publish_interval, 5, "HMI Status publish interval.");

DEFINE_string(current_mode_db_key, "/apollo/hmi/status:current_mode",
              "Key to store hmi_status.current_mode in KV DB.");

DEFINE_string(default_hmi_mode, "Mkz Standard Debug",
              "Default HMI Mode when there is no cache.");

DEFINE_string(container_meta_ini, "/apollo/meta.ini",
              "Container meta info file.");

namespace apollo {
namespace dreamview {
namespace {

using apollo::canbus::Chassis;
using apollo::common::DriveEvent;
using apollo::common::KVDB;
using apollo::common::time::Clock;
using apollo::common::util::StrAppend;
using apollo::common::util::StrCat;
using apollo::control::DrivingAction;
using apollo::cyber::Node;
using apollo::monitor::ComponentStatus;
using apollo::monitor::SystemStatus;
using google::protobuf::Map;
using RLock = boost::shared_lock<boost::shared_mutex>;
using WLock = boost::unique_lock<boost::shared_mutex>;

constexpr char kNavigationModeName[] = "Navigation";

// Convert a string to be title-like. E.g.: "hello_world" -> "Hello World".
std::string TitleCase(const std::string& origin) {
  static const std::string kDelimiter = "_";
  std::vector<std::string> parts =
      apollo::common::util::StringTokenizer::Split(origin, kDelimiter);
  for (auto& part : parts) {
    if (!part.empty()) {
      // Upper case the first char.
      part[0] = static_cast<char>(toupper(part[0]));
    }
  }

  return apollo::common::util::PrintIter(parts);
}

// List subdirs and return a dict of {subdir_title: subdir_path}.
Map<std::string, std::string> ListDirAsDict(const std::string& dir) {
  Map<std::string, std::string> result;
  const auto subdirs = apollo::common::util::ListSubPaths(dir);
  for (const auto& subdir : subdirs) {
    const auto subdir_title = TitleCase(subdir);
    const auto subdir_path = StrCat(dir, "/", subdir);
    result.insert({subdir_title, subdir_path});
  }
  return result;
}

// List files by pattern and return a dict of {file_title: file_path}.
Map<std::string, std::string> ListFilesAsDict(const std::string& dir,
                                              const std::string& extension) {
  Map<std::string, std::string> result;
  const std::string pattern = StrCat(dir, "/*", extension);
  for (const std::string& file_path : apollo::common::util::Glob(pattern)) {
    // Remove the extention and convert to title case as the file title.
    const std::string filename = apollo::common::util::GetFileName(file_path);
    const std::string file_title =
        TitleCase(filename.substr(0, filename.length() - extension.length()));
    result.insert({file_title, file_path});
  }
  return result;
}

template <class FlagType, class ValueType>
void SetGlobalFlag(const std::string& flag_name, const ValueType& value,
                   FlagType* flag) {
  static constexpr char kGlobalFlagfile[] =
      "/apollo/modules/common/data/global_flagfile.txt";
  if (*flag != value) {
    *flag = value;
    // Overwrite global flagfile.
    std::ofstream fout(kGlobalFlagfile, std::ios_base::app);
    CHECK(fout) << "Fail to open global flagfile " << kGlobalFlagfile;
    fout << "\n--" << flag_name << "=" << value << std::endl;
  }
}

void System(const std::string& cmd) {
  const int ret = std::system(cmd.c_str());
  if (ret == 0) {
    AINFO << "SUCCESS: " << cmd;
  } else {
    AERROR << "FAILED(" << ret << "): " << cmd;
  }
}

std::string GetDockerImage() {
  const char* docker_image = std::getenv("DOCKER_IMG");
  return docker_image != nullptr
      ? std::string(docker_image) : std::string("");
}

}  // namespace

HMIWorker::HMIWorker(const std::shared_ptr<Node>& node)
    : config_(LoadConfig()), node_(node) {
  InitStatus();
}

void HMIWorker::Start() {
  InitReadersAndWriters();
  RegisterStatusUpdateHandler(
      [this](const bool status_changed, HMIStatus* status) {
        apollo::common::util::FillHeader("HMI", status);
        status_writer_->Write(*status);
        status->clear_header();
{'fraction_non_alphanumeric': 0.16283139382273165, 'fraction_numerical': 0.002274914690699099, 'mean_word_length': 4.556635877491493, 'pattern_counts': {'":': 0, '<': 75, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2001184', 'n_tokens_mistral': 3575, 'n_tokens_neox': 3464, 'n_words': 850}