// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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 "kudu/subprocess/subprocess_proxy.h"

#include <string>
#include <vector>

#include "kudu/gutil/strings/join.h"
#include "kudu/gutil/strings/substitute.h"

using std::string;
using std::vector;
using strings::Substitute;

namespace kudu {
namespace subprocess {

namespace {
// Helpers to generate log4j2 properties suitable for a Java-based subprocess.
// TODO(awong): if our logging requirements get more complex, we should
// consider a builder for these.

// $0: appender instance
// $1: appender name
// $2: log directory
// $3: log filename base - new logs will be called "{log directory}/{log
//     filename base}.log" and will roll to include the date in the name
// $4: rollover policy size in MB
// $5: number of files max
const char* kLog4j2RollingPropertiesTemplate = R"(
appender.$0.type = RollingFile
appender.$0.name = $1
appender.$0.layout.type = PatternLayout
appender.$0.layout.pattern = %d{yyyy-MM-dd HH:mm:ss.SSS} [%p - %t] (%F:%L) %m%n
appender.$0.filename = $2/$3.log
appender.$0.filePattern = $2/$3.%d{yyyyMMdd-HHmmss}.log.gz
appender.$0.policies.type = Policies
appender.$0.policies.size.type = SizeBasedTriggeringPolicy
appender.$0.policies.size.size = $4 MB
appender.$0.strategy.type = DefaultRolloverStrategy
appender.$0.strategy.max = $5
)";

// $0: appender instance
// $1: appender name
const char* kLog4j2ConsoleProperties = R"(
appender.$0.type = Console
appender.$0.name = $1
appender.$0.layout.type = PatternLayout
appender.$0.layout.pattern = %d{yyyy-MM-dd HH:mm:ss.SSS} [%p - %t] (%F:%L) %m%n
)";

// $0: name of the creator of these properties (e.g. the program name)
// $1: comma-separated list of appender instances
// $2: newline-separated list of appender configs
// $3: log level (supports "all", "debug", "info", "warn", "error", "fatal")
// $4: comma-separated list of appender refs
// $5: newline-separated list of appender ref name specifications
const char* kLog4j2PropertiesTemplate = R"(
# THIS FILE WAS GENERATED BY $0.

status = error
name = PropertiesConfig
appenders = $1
$2
rootLogger.level = $3
rootLogger.appenderRefs = $4
$5
)";
} // anonymous namespace

string Log4j2Properties(const string& creator, const string& log_dir,
                        const string& log_filename, int rollover_size_mb,
                        int max_files, const string& log_level,
                        bool log_to_stdout) {
  static const char* kRollingInstance = "rollingFile";
  static const char* kRollingName = "RollingFileAppender";
  static const char* kRollingRef = "rolling";
  vector<string> appender_instances = { kRollingInstance };
  vector<string> appender_names = { kRollingName };
  vector<string> appender_configs = {
    Substitute(kLog4j2RollingPropertiesTemplate, kRollingInstance, kRollingName,
               log_dir, log_filename, rollover_size_mb, max_files)
  };
  vector<string> appender_refs = { kRollingRef };
  if (log_to_stdout) {
    static const char* kConsoleInstance = "console";
    static const char* kConsoleName = "SystemOutAppender";
    static const char* kConsoleRef = "stdout";
    appender_instances.emplace_back(kConsoleInstance);
    appender_names.emplace_back(kConsoleName);
    appender_refs.emplace_back(kConsoleRef);
    appender_configs.emplace_back(
        strings::Substitute(kLog4j2ConsoleProperties, kConsoleInstance, kConsoleName));
  }

  DCHECK_EQ(appender_refs.size(), appender_names.size());
  vector<string> appender_ref_name_specs(appender_refs.size());
  for (int i = 0; i < appender_refs.size(); i++) {
    appender_ref_name_specs.emplace_back(
        strings::Substitute("rootLogger.appenderRef.$0.ref = $1",
                            appender_refs[i], appender_names[i]));
  }
  return Substitute(kLog4j2PropertiesTemplate, creator,
                    JoinStrings(appender_instances, ", "),
                    JoinStrings(appender_configs, "\n"),
                    log_level,
                    JoinStrings(appender_refs, ", "),
                    JoinStrings(appender_ref_name_specs, "\n"));
}

}  // namespace subprocess
}  // namespace kudu
