// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <algorithm>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>

#include "flutter/fml/native_library.h"
#include "flutter/fml/paths.h"
#include "flutter/shell/version/version.h"

// Include once for the default enum definition.
#include "flutter/shell/common/switches.h"

#undef FLUTTER_SHELL_COMMON_SWITCHES_H_

struct SwitchDesc {
  flutter::Switch sw;
  const std::string_view flag;
  const char* help;
};

#undef DEF_SWITCHES_START
#undef DEF_SWITCH
#undef DEF_SWITCHES_END

// clang-format off
#define DEF_SWITCHES_START static const struct SwitchDesc gSwitchDescs[] = {
#define DEF_SWITCH(p_swtch, p_flag, p_help) \
  { flutter::Switch:: p_swtch, p_flag, p_help },
#define DEF_SWITCHES_END };
// clang-format on

// List of common and safe VM flags to allow to be passed directly to the VM.
#if FLUTTER_RELEASE

// clang-format off
static const std::string kAllowedDartFlags[] = {
    "--enable-isolate-groups",
    "--no-enable-isolate-groups",
};
// clang-format on

#else

// clang-format off
static const std::string kAllowedDartFlags[] = {
    "--enable-isolate-groups",
    "--no-enable-isolate-groups",
    "--enable_mirrors",
    "--enable-service-port-fallback",
    "--max_profile_depth",
    "--profile_period",
    "--random_seed",
    "--sample-buffer-duration",
    "--trace-kernel",
    "--trace-reload",
    "--trace-reload-verbose",
    "--write-service-info",
    "--max_subtype_cache_entries",
    "--enable-asserts",
};
// clang-format on

#endif  // FLUTTER_RELEASE

// Include again for struct definition.
#include "flutter/shell/common/switches.h"

// Define symbols for the ICU data that is linked into the Flutter library on
// Android.  This is a workaround for crashes seen when doing dynamic lookups
// of the engine's own symbols on some older versions of Android.
#if FML_OS_ANDROID
extern uint8_t _binary_icudtl_dat_start[];
extern size_t _binary_icudtl_dat_size;

static std::unique_ptr<fml::Mapping> GetICUStaticMapping() {
  return std::make_unique<fml::NonOwnedMapping>(_binary_icudtl_dat_start,
                                                _binary_icudtl_dat_size);
}
#endif

namespace flutter {

void PrintUsage(const std::string& executable_name) {
  std::cerr << std::endl << "  " << executable_name << std::endl << std::endl;

  std::cerr << "Versions: " << std::endl << std::endl;

  std::cerr << "Flutter Engine Version: " << GetFlutterEngineVersion()
            << std::endl;

  std::cerr << "Flutter Content Hash: " << GetFlutterContentHash() << std::endl;

  std::cerr << "Skia Version: " << GetSkiaVersion() << std::endl;

  std::cerr << "Dart Version: " << GetDartVersion() << std::endl << std::endl;

  std::cerr << "Available Flags:" << std::endl;

  const uint32_t column_width = 80;

  const uint32_t flags_count = static_cast<uint32_t>(Switch::Sentinel);

  uint32_t max_width = 2;
  for (uint32_t i = 0; i < flags_count; i++) {
    auto desc = gSwitchDescs[i];
    max_width = std::max<uint32_t>(desc.flag.size() + 2, max_width);
  }

  const uint32_t help_width = column_width - max_width - 3;

  std::cerr << std::string(column_width, '-') << std::endl;
  for (uint32_t i = 0; i < flags_count; i++) {
    auto desc = gSwitchDescs[i];

    std::cerr << std::setw(max_width)
              << std::string("--") +
                     std::string{desc.flag.data(), desc.flag.size()}
              << " : ";

    std::istringstream stream(desc.help);
    int32_t remaining = help_width;

    std::string word;
    while (stream >> word && remaining > 0) {
      remaining -= (word.size() + 1);
      if (remaining <= 0) {
        std::cerr << std::endl
                  << std::string(max_width, ' ') << "   " << word << " ";
        remaining = help_width;
      } else {
        std::cerr << word << " ";
      }
    }

    std::cerr << std::endl;
  }
  std::cerr << std::string(column_width, '-') << std::endl;
}

const std::string_view FlagForSwitch(Switch swtch) {
  for (uint32_t i = 0; i < static_cast<uint32_t>(Switch::Sentinel); i++) {
    if (gSwitchDescs[i].sw == swtch) {
      return gSwitchDescs[i].flag;
    }
  }
  return std::string_view();
}

static std::vector<std::string> ParseCommaDelimited(const std::string& input) {
  std::istringstream ss(input);
  std::vector<std::string> result;
  std::string token;
  while (std::getline(ss, token, ',')) {
    result.push_back(token);
  }
  return result;
}

static bool IsAllowedDartVMFlag(const std::string& flag) {
  for (uint32_t i = 0; i < std::size(kAllowedDartFlags); ++i) {
    const std::string& allowed = kAllowedDartFlags[i];
    // Check that the prefix of the flag matches one of the allowed flags. This
    // is to handle cases where flags take arguments, such as in
    // "--max_profile_depth 1".
    //
    // We don't need to worry about cases like "--safe --sneaky_dangerous" as
    // the VM will discard these as a single unrecognized flag.
    if (flag.length() >= allowed.length() &&
        std::equal(allowed.begin(), allowed.end(), flag.begin())) {
      return true;
    }
  }
  return false;
}

template <typename T>
static bool GetSwitchValue(const fml::CommandLine& command_line,
                           Switch sw,
                           T* result) {
  std::string switch_string;

  if (!command_line.GetOptionValue(FlagForSwitch(sw), &switch_string)) {
    return false;
  }

  std::stringstream stream(switch_string);
  T value = 0;
  if (stream >> value) {
    *result = value;
    return true;
  }

  return false;
}

std::unique_ptr<fml::Mapping> GetSymbolMapping(
    const std::string& symbol_prefix,
    const std::string& native_lib_path) {
  const uint8_t* mapping = nullptr;
  intptr_t size;

  auto lookup_symbol = [&mapping, &size, symbol_prefix](
                           const fml::RefPtr<fml::NativeLibrary>& library) {
    mapping = library->ResolveSymbol((symbol_prefix + "_start").c_str());
    size = reinterpret_cast<intptr_t>(
        library->ResolveSymbol((symbol_prefix + "_size").c_str()));
  };

  fml::RefPtr<fml::NativeLibrary> library =
      fml::NativeLibrary::CreateForCurrentProcess();
  lookup_symbol(library);

  if (!(mapping && size)) {
    // Symbol lookup for the current process fails on some devices.  As a
    // fallback, try doing the lookup based on the path to the Flutter library.
    library = fml::NativeLibrary::Create(native_lib_path.c_str());
    lookup_symbol(library);
  }

  FML_CHECK(mapping && size) << "Unable to resolve symbols: " << symbol_prefix;
  return std::make_unique<fml::NonOwnedMapping>(mapping, size);
}

Settings SettingsFromCommandLine(const fml::CommandLine& command_line) {
  Settings settings = {};

  // Set executable name.
  if (command_line.has_argv0()) {
    settings.executable_name = command_line.argv0();
  }

  // Enable the VM Service
  settings.enable_vm_service =
      !command_line.HasOption(FlagForSwitch(Switch::DisableVMService));

  // Enable mDNS VM Service Publication
  settings.enable_vm_service_publication = !command_line.HasOption(
      FlagForSwitch(Switch::DisableVMServicePublication));

  // Set VM Service Host
  if (command_line.HasOption(FlagForSwitch(Switch::DeviceVMServiceHost))) {
    command_line.GetOptionValue(FlagForSwitch(Switch::DeviceVMServiceHost),
                                &settings.vm_service_host);
  }
  // Default the VM Service port based on --ipv6 if not set.
  if (settings.vm_service_host.empty()) {
    settings.vm_service_host =
        command_line.HasOption(FlagForSwitch(Switch::IPv6)) ? "::1"
                                                            : "127.0.0.1";
  }

  // Set VM Service Port
  if (command_line.HasOption(FlagForSwitch(Switch::DeviceVMServicePort))) {
    if (!GetSwitchValue(command_line, Switch::DeviceVMServicePort,
                        &settings.vm_service_port)) {
      FML_LOG(INFO)
          << "VM Service port specified was malformed. Will default to "
          << settings.vm_service_port;
    }
  }

  settings.may_insecurely_connect_to_all_domains = !command_line.HasOption(
      FlagForSwitch(Switch::DisallowInsecureConnections));

  command_line.GetOptionValue(FlagForSwitch(Switch::DomainNetworkPolicy),
                              &settings.domain_network_policy);

  // Disable need for authentication codes for VM service communication, if
  // specified.
  settings.disable_service_auth_codes =
      command_line.HasOption(FlagForSwitch(Switch::DisableServiceAuthCodes));

  // Allow fallback to automatic port selection if binding to a specified port
  // fails.
  settings.enable_service_port_fallback =
      command_line.HasOption(FlagForSwitch(Switch::EnableServicePortFallback));

  // Checked mode overrides.
  settings.disable_dart_asserts =
      command_line.HasOption(FlagForSwitch(Switch::DisableDartAsserts));

  settings.start_paused =
      command_line.HasOption(FlagForSwitch(Switch::StartPaused));

  settings.enable_checked_mode =
      command_line.HasOption(FlagForSwitch(Switch::EnableCheckedMode));

  settings.enable_dart_profiling =
      command_line.HasOption(FlagForSwitch(Switch::EnableDartProfiling));

  settings.profile_startup =
      command_line.HasOption(FlagForSwitch(Switch::ProfileStartup));

  settings.enable_software_rendering =
      command_line.HasOption(FlagForSwitch(Switch::EnableSoftwareRendering));

  settings.endless_trace_buffer =
      command_line.HasOption(FlagForSwitch(Switch::EndlessTraceBuffer));

  settings.trace_startup =
      command_line.HasOption(FlagForSwitch(Switch::TraceStartup));

  settings.enable_serial_gc =
      command_line.HasOption(FlagForSwitch(Switch::EnableSerialGC));

#if !FLUTTER_RELEASE
  settings.trace_skia = true;

  if (command_line.HasOption(FlagForSwitch(Switch::TraceSkia))) {
    // If --trace-skia is specified, then log all Skia events.
    settings.trace_skia_allowlist.reset();
  } else {
    std::string trace_skia_allowlist;
    command_line.GetOptionValue(FlagForSwitch(Switch::TraceSkiaAllowlist),
                                &trace_skia_allowlist);
    if (trace_skia_allowlist.size()) {
      settings.trace_skia_allowlist = ParseCommaDelimited(trace_skia_allowlist);
    } else {
      settings.trace_skia_allowlist = {"skia.shaders"};
    }
  }
#endif  // !FLUTTER_RELEASE

  std::string trace_allowlist;
  command_line.GetOptionValue(FlagForSwitch(Switch::TraceAllowlist),
                              &trace_allowlist);
  settings.trace_allowlist = ParseCommaDelimited(trace_allowlist);

  settings.trace_systrace =
      command_line.HasOption(FlagForSwitch(Switch::TraceSystrace));

  command_line.GetOptionValue(FlagForSwitch(Switch::TraceToFile),
                              &settings.trace_to_file);

  settings.profile_microtasks =
      command_line.HasOption(FlagForSwitch(Switch::ProfileMicrotasks));

  settings.skia_deterministic_rendering_on_cpu =
      command_line.HasOption(FlagForSwitch(Switch::SkiaDeterministicRendering));

  settings.verbose_logging =
      command_line.HasOption(FlagForSwitch(Switch::VerboseLogging));

  command_line.GetOptionValue(FlagForSwitch(Switch::FlutterAssetsDir),
                              &settings.assets_path);

  std::vector<std::string_view> aot_shared_library_name =
      command_line.GetOptionValues(FlagForSwitch(Switch::AotSharedLibraryName));

  std::vector<std::string_view> vmservice_shared_library_name =
      command_line.GetOptionValues(
          FlagForSwitch(Switch::AotVMServiceSharedLibraryName));
  for (auto path : vmservice_shared_library_name) {
    settings.vmservice_snapshot_library_path.emplace_back(path);
  }

  std::string snapshot_asset_path;
  command_line.GetOptionValue(FlagForSwitch(Switch::SnapshotAssetPath),
                              &snapshot_asset_path);

  std::string vm_snapshot_data_filename;
  command_line.GetOptionValue(FlagForSwitch(Switch::VmSnapshotData),
                              &vm_snapshot_data_filename);

  command_line.GetOptionValue(FlagForSwitch(Switch::Route), &settings.route);

  std::string vm_snapshot_instr_filename;
  command_line.GetOptionValue(FlagForSwitch(Switch::VmSnapshotInstructions),
                              &vm_snapshot_instr_filename);

  std::string isolate_snapshot_data_filename;
  command_line.GetOptionValue(FlagForSwitch(Switch::IsolateSnapshotData),
                              &isolate_snapshot_data_filename);

  std::string isolate_snapshot_instr_filename;
  command_line.GetOptionValue(
      FlagForSwitch(Switch::IsolateSnapshotInstructions),
      &isolate_snapshot_instr_filename);

  if (!aot_shared_library_name.empty()) {
    for (std::string_view name : aot_shared_library_name) {
      settings.application_library_path.emplace_back(name);
    }
  } else if (!snapshot_asset_path.empty()) {
    settings.vm_snapshot_data_path =
        fml::paths::JoinPaths({snapshot_asset_path, vm_snapshot_data_filename});
    settings.vm_snapshot_instr_path = fml::paths::JoinPaths(
        {snapshot_asset_path, vm_snapshot_instr_filename});
    settings.isolate_snapshot_data_path = fml::paths::JoinPaths(
        {snapshot_asset_path, isolate_snapshot_data_filename});
    settings.isolate_snapshot_instr_path = fml::paths::JoinPaths(
        {snapshot_asset_path, isolate_snapshot_instr_filename});
  }

  command_line.GetOptionValue(FlagForSwitch(Switch::CacheDirPath),
                              &settings.temp_directory_path);

  bool leak_vm = "true" == command_line.GetOptionValueWithDefault(
                               FlagForSwitch(Switch::LeakVM), "true");
  settings.leak_vm = leak_vm;

  if (settings.icu_initialization_required) {
    command_line.GetOptionValue(FlagForSwitch(Switch::ICUDataFilePath),
                                &settings.icu_data_path);
    if (command_line.HasOption(FlagForSwitch(Switch::ICUSymbolPrefix))) {
      std::string icu_symbol_prefix, native_lib_path;
      command_line.GetOptionValue(FlagForSwitch(Switch::ICUSymbolPrefix),
                                  &icu_symbol_prefix);
      command_line.GetOptionValue(FlagForSwitch(Switch::ICUNativeLibPath),
                                  &native_lib_path);

#if FML_OS_ANDROID
      settings.icu_mapper = GetICUStaticMapping;
#else
      settings.icu_mapper = [icu_symbol_prefix, native_lib_path] {
        return GetSymbolMapping(icu_symbol_prefix, native_lib_path);
      };
#endif
    }
  }

  settings.use_test_fonts =
      command_line.HasOption(FlagForSwitch(Switch::UseTestFonts));
  settings.use_asset_fonts =
      !command_line.HasOption(FlagForSwitch(Switch::DisableAssetFonts));

#if FML_OS_IOS || FML_OS_IOS_SIMULATOR || SLIMPELLER
// On these configurations, the Impeller flags are completely ignored with the
// default taking hold.
#else   // FML_OS_IOS && !FML_OS_IOS_SIMULATOR
  {
    std::string enable_impeller_value;
    if (command_line.GetOptionValue(FlagForSwitch(Switch::EnableImpeller),
                                    &enable_impeller_value)) {
      settings.enable_impeller =
          enable_impeller_value.empty() || "true" == enable_impeller_value;
    }
  }
#endif  // FML_OS_IOS && !FML_OS_IOS_SIMULATOR

  {
    std::string impeller_backend_value;
    if (command_line.GetOptionValue(FlagForSwitch(Switch::ImpellerBackend),
                                    &impeller_backend_value)) {
      if (!impeller_backend_value.empty()) {
        settings.requested_rendering_backend = impeller_backend_value;
      }
    }
  }

  settings.enable_vulkan_validation =
      command_line.HasOption(FlagForSwitch(Switch::EnableVulkanValidation));
  settings.enable_opengl_gpu_tracing =
      command_line.HasOption(FlagForSwitch(Switch::EnableOpenGLGPUTracing));
  settings.enable_vulkan_gpu_tracing =
      command_line.HasOption(FlagForSwitch(Switch::EnableVulkanGPUTracing));

  settings.enable_embedder_api =
      command_line.HasOption(FlagForSwitch(Switch::EnableEmbedderAPI));

  settings.prefetched_default_font_manager = command_line.HasOption(
      FlagForSwitch(Switch::PrefetchedDefaultFontManager));

  std::string all_dart_flags;
  if (command_line.GetOptionValue(FlagForSwitch(Switch::DartFlags),
                                  &all_dart_flags)) {
    // Assume that individual flags are comma separated.
    std::vector<std::string> flags = ParseCommaDelimited(all_dart_flags);
    for (const auto& flag : flags) {
      if (!IsAllowedDartVMFlag(flag)) {
        FML_LOG(FATAL) << "Encountered disallowed Dart VM flag: " << flag;
      }
      settings.dart_flags.push_back(flag);
    }
  }

#if !FLUTTER_RELEASE
  command_line.GetOptionValue(FlagForSwitch(Switch::LogTag), &settings.log_tag);
#endif

  settings.dump_skp_on_shader_compilation =
      command_line.HasOption(FlagForSwitch(Switch::DumpSkpOnShaderCompilation));

  settings.cache_sksl =
      command_line.HasOption(FlagForSwitch(Switch::CacheSkSL));

  settings.purge_persistent_cache =
      command_line.HasOption(FlagForSwitch(Switch::PurgePersistentCache));

  if (command_line.HasOption(FlagForSwitch(Switch::OldGenHeapSize))) {
    std::string old_gen_heap_size;
    command_line.GetOptionValue(FlagForSwitch(Switch::OldGenHeapSize),
                                &old_gen_heap_size);
    settings.old_gen_heap_size = std::stoi(old_gen_heap_size);
  }

  if (command_line.HasOption(
          FlagForSwitch(Switch::ResourceCacheMaxBytesThreshold))) {
    std::string resource_cache_max_bytes_threshold;
    command_line.GetOptionValue(
        FlagForSwitch(Switch::ResourceCacheMaxBytesThreshold),
        &resource_cache_max_bytes_threshold);
    settings.resource_cache_max_bytes_threshold =
        std::stoi(resource_cache_max_bytes_threshold);
  }

  settings.enable_platform_isolates =
      command_line.HasOption(FlagForSwitch(Switch::EnablePlatformIsolates));

  settings.enable_surface_control = command_line.HasOption(
      FlagForSwitch(Switch::EnableAndroidSurfaceControl));

  if (command_line.HasOption(
          FlagForSwitch(Switch::DisableMergedPlatformUIThread))) {
    settings.merged_platform_ui_thread =
        Settings::MergedPlatformUIThread::kDisabled;
  } else if (command_line.HasOption(
                 FlagForSwitch(Switch::MergedPlatformUIThread))) {
    std::string merged_platform_ui;
    command_line.GetOptionValue(FlagForSwitch(Switch::MergedPlatformUIThread),
                                &merged_platform_ui);
    if (merged_platform_ui == "enabled") {
      settings.merged_platform_ui_thread =
          Settings::MergedPlatformUIThread::kEnabled;
    } else if (merged_platform_ui == "disabled") {
      settings.merged_platform_ui_thread =
          Settings::MergedPlatformUIThread::kDisabled;
    } else if (merged_platform_ui == "mergeAfterLaunch") {
      settings.merged_platform_ui_thread =
          Settings::MergedPlatformUIThread::kMergeAfterLaunch;
    }
  }

  settings.enable_flutter_gpu =
      command_line.HasOption(FlagForSwitch(Switch::EnableFlutterGPU));
  settings.impeller_enable_lazy_shader_mode =
      command_line.HasOption(FlagForSwitch(Switch::ImpellerLazyShaderMode));
  settings.impeller_antialiased_lines =
      command_line.HasOption(FlagForSwitch(Switch::ImpellerAntialiasLines));

  return settings;
}

}  // namespace flutter
