// Copyright 2017 The Fuchsia 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 "garnet/bin/trace/spec.h"

#include <memory>

#include <rapidjson/document.h>
#include <rapidjson/error/en.h>
#include <rapidjson/schema.h>
#include <rapidjson/stringbuffer.h>

#include "lib/fxl/logging.h"

namespace tracing {
namespace {

// Top-level schema.
const char kRootSchema[] = R"({
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "test_name": {
      "type": "string"
    },
    "app": {
      "type": "string"
    },
    "args": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "spawn": {
      "type": "boolean"
    },
    "categories": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "buffering_mode": {
      "type": "string"
    },
    "buffer_size_in_mb": {
      "type": "integer",
      "minimum": 1
    },
    "duration": {
      "type": "integer",
      "minimum": 0
    },
    "measure": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string"
          },
          "output_test_name": {
            "type": "string"
          },
          "split_first": {
            "type": "boolean"
          },
          "expected_sample_count": {
            "type": "integer",
            "minimum": 1
          },
          "required": ["type"]
        }
      }
    },
    "test_suite_name": {
      "type": "string"
    }
  }
})";

const char kTestNameKey[] = "test_name";
const char kAppKey[] = "app";
const char kArgsKey[] = "args";
const char kSpawnKey[] = "spawn";
const char kDurationKey[] = "duration";
const char kCategoriesKey[] = "categories";
const char kBufferingModeKey[] = "buffering_mode";
const char kBufferSizeInMbKey[] = "buffer_size_in_mb";
const char kMeasurementsKey[] = "measure";
const char kTypeKey[] = "type";
const char kOutputTestName[] = "output_test_name";
const char kSplitFirstKey[] = "split_first";
const char kExpectedSampleCountKey[] = "expected_sample_count";
const char kTestSuiteNameKey[] = "test_suite_name";
const char kMeasureDurationType[] = "duration";
const char kMeasureArgumentValueType[] = "argument_value";
const char kMeasureTimeBetweenType[] = "time_between";

// Schema for "duration" measurements.
const char kDurationSchema[] = R"({
  "type": "object",
  "properties": {
    "event_category": {
      "type": "string"
    },
    "event_name": {
      "type": "string"
    }
  },
  "required": ["event_category", "event_name"]
})";
const char kEventCategoryKey[] = "event_category";
const char kEventNameKey[] = "event_name";

// Schema for "time between" measurements.
const char kTimeBetweenSchema[] = R"({
  "type": "object",
  "properties": {
    "first_event_name": {
      "type": "string"
    },
    "first_event_category": {
      "type": "string"
    },
    "first_event_anchor": {
      "type": "string"
    },
    "second_event_name": {
      "type": "string"
    },
    "second_event_category": {
      "type": "string"
    },
    "second_event_anchor": {
      "type": "string"
    }
  },
  "required": [
    "first_event_name", "first_event_category", "second_event_name",
    "second_event_category"
  ]
})";
const char kFirstEventNameKey[] = "first_event_name";
const char kFirstEventCategoryKey[] = "first_event_category";
const char kFirstEventAnchorKey[] = "first_event_anchor";
const char kSecondEventNameKey[] = "second_event_name";
const char kSecondEventCategoryKey[] = "second_event_category";
const char kSecondEventAnchorKey[] = "second_event_anchor";
const char kAnchorBegin[] = "begin";
const char kAnchorEnd[] = "end";

// Schema for "argument value" measurements.
const char kArgumentValueSchema[] = R"({
  "type": "object",
  "properties": {
    "event_category": {
      "type": "string"
    },
    "event_name": {
      "type": "string"
    },
    "argument_name": {
      "type": "string"
    },
    "argument_unit": {
      "type": "string"
    }
  },
  "required": ["event_category", "event_name", "argument_name", "argument_unit"]
})";
const char kArgumentNameKey[] = "argument_name";
const char kArgumentUnitKey[] = "argument_unit";

bool DecodeMeasureDuration(const rapidjson::Value& value,
                           measure::DurationSpec* result) {
  result->event.name = value[kEventNameKey].GetString();
  result->event.category = value[kEventCategoryKey].GetString();
  return true;
}

bool DecodeMeasureArgumentValue(const rapidjson::Value& value,
                                measure::ArgumentValueSpec* result) {
  result->event.name = value[kEventNameKey].GetString();
  result->event.category = value[kEventCategoryKey].GetString();
  result->argument_name = value[kArgumentNameKey].GetString();
  result->argument_unit = value[kArgumentUnitKey].GetString();
  return true;
}

bool DecodeAnchor(std::string anchor_str, const char* key,
                  measure::Anchor* result) {
  if (anchor_str == kAnchorBegin) {
    *result = measure::Anchor::Begin;
  } else if (anchor_str == kAnchorEnd) {
    *result = measure::Anchor::End;
  } else {
    FXL_LOG(ERROR) << "Incorrect value of " << key;
    return false;
  }

  return true;
}

bool DecodeMeasureTimeBetween(const rapidjson::Value& value,
                              measure::TimeBetweenSpec* result) {
  result->first_event.name = value[kFirstEventNameKey].GetString();
  result->first_event.category = value[kFirstEventCategoryKey].GetString();
  if (value.HasMember(kFirstEventAnchorKey)) {
    if (!DecodeAnchor(value[kFirstEventAnchorKey].GetString(),
                      kFirstEventAnchorKey, &result->first_anchor)) {
      return false;
    }
  }
  result->second_event.name = value[kSecondEventNameKey].GetString();
  result->second_event.category = value[kSecondEventCategoryKey].GetString();
  if (value.HasMember(kSecondEventAnchorKey)) {
    if (!DecodeAnchor(value[kSecondEventAnchorKey].GetString(),
                      kSecondEventAnchorKey, &result->second_anchor)) {
      return false;
    }
  }
  return true;
}

std::unique_ptr<rapidjson::SchemaDocument> InitSchema(const char schemaSpec[]) {
  rapidjson::Document schema_document;
  if (schema_document.Parse(schemaSpec).HasParseError()) {
    FXL_DCHECK(false) << "Schema validation spec itself is not valid JSON.";
    return nullptr;
  }
  return std::make_unique<rapidjson::SchemaDocument>(schema_document);
}

bool ValidateSchema(const rapidjson::Value& value,
                    const rapidjson::SchemaDocument& schema) {
  rapidjson::SchemaValidator validator(schema);
  if (!value.Accept(validator)) {
    rapidjson::StringBuffer uri_buffer;
    validator.GetInvalidSchemaPointer().StringifyUriFragment(uri_buffer);
    FXL_LOG(ERROR) << "Incorrect schema of tracing spec at "
                   << uri_buffer.GetString() << " , schema violation: "
                   << validator.GetInvalidSchemaKeyword();
    return false;
  }
  return true;
}

}  // namespace

bool DecodeSpec(const std::string& json, Spec* spec) {
  // Initialize schemas for JSON validation.
  auto root_schema = InitSchema(kRootSchema);
  auto duration_schema = InitSchema(kDurationSchema);
  auto time_between_schema = InitSchema(kTimeBetweenSchema);
  auto argument_value_schema = InitSchema(kArgumentValueSchema);
  if (!root_schema || !duration_schema || !time_between_schema ||
      !argument_value_schema) {
    return false;
  }

  Spec result;
  rapidjson::Document document;
  document.Parse<rapidjson::kParseCommentsFlag>(json.c_str(), json.size());
  if (document.HasParseError()) {
    auto offset = document.GetErrorOffset();
    auto code = document.GetParseError();
    FXL_LOG(ERROR) << "Couldn't parse the tracing spec file: offset " << offset
                   << ", " << GetParseError_En(code);
    return false;
  }
  if (!ValidateSchema(document, *root_schema)) {
    return false;
  }

  if (document.HasMember(kTestNameKey)) {
    result.test_name = std::make_unique<std::string>(
        document[kTestNameKey].GetString());
  }

  if (document.HasMember(kAppKey)) {
    result.app = std::make_unique<std::string>(document[kAppKey].GetString());
  }

  if (document.HasMember(kArgsKey)) {
    result.args = std::make_unique<std::vector<std::string>>();
    for (auto& arg_value : document[kArgsKey].GetArray()) {
      result.args->push_back(arg_value.GetString());
    }
  }

  if (document.HasMember(kSpawnKey)) {
    result.spawn = std::make_unique<bool>(document[kSpawnKey].GetBool());
  }

  if (document.HasMember(kCategoriesKey)) {
    result.categories = std::make_unique<std::vector<std::string>>();
    for (auto& arg_value : document[kCategoriesKey].GetArray()) {
      result.categories->push_back(arg_value.GetString());
    }
  }

  if (document.HasMember(kBufferingModeKey)) {
    result.buffering_mode = std::make_unique<std::string>(
        document[kBufferingModeKey].GetString());
  }

  if (document.HasMember(kBufferSizeInMbKey)) {
    result.buffer_size_in_mb = std::make_unique<size_t>(
        document[kBufferSizeInMbKey].GetUint());
  }

  if (document.HasMember(kDurationKey)) {
    result.duration = std::make_unique<fxl::TimeDelta>(
        fxl::TimeDelta::FromSeconds(document[kDurationKey].GetUint()));
  }

  if (document.HasMember(kTestSuiteNameKey)) {
    result.test_suite_name = std::make_unique<std::string>(
      document[kTestSuiteNameKey].GetString());
  }

  if (!document.HasMember(kMeasurementsKey)) {
    *spec = std::move(result);
    return true;
  }
  result.measurements = std::make_unique<measure::Measurements>();

  // Used to assign a unique id to each measurement, in the order they were
  // defined.
  uint64_t counter = 0u;
  for (auto& measurement : document[kMeasurementsKey].GetArray()) {
    std::string type = measurement[kTypeKey].GetString();
    measure::MeasurementSpecCommon common;
    common.id = counter;

    if (measurement.HasMember(kOutputTestName)) {
      common.output_test_name = measurement[kOutputTestName].GetString();
    }

    if (measurement.HasMember(kSplitFirstKey)) {
      common.split_first = measurement[kSplitFirstKey].GetBool();
    }

    if (measurement.HasMember(kExpectedSampleCountKey)) {
      common.expected_sample_count =
          measurement[kExpectedSampleCountKey].GetUint();
    }

    if (type == kMeasureDurationType) {
      measure::DurationSpec spec;
      spec.common = std::move(common);
      if (!ValidateSchema(measurement, *duration_schema) ||
          !DecodeMeasureDuration(measurement, &spec)) {
        return false;
      }
      result.measurements->duration.push_back(std::move(spec));
    } else if (type == kMeasureTimeBetweenType) {
      measure::TimeBetweenSpec spec;
      spec.common = std::move(common);
      if (!ValidateSchema(measurement, *time_between_schema) ||
          !DecodeMeasureTimeBetween(measurement, &spec)) {
        return false;
      }
      result.measurements->time_between.push_back(std::move(spec));
    } else if (type == kMeasureArgumentValueType) {
      measure::ArgumentValueSpec spec;
      spec.common = std::move(common);
      if (!ValidateSchema(measurement, *argument_value_schema) ||
          !DecodeMeasureArgumentValue(measurement, &spec)) {
        return false;
      }
      result.measurements->argument_value.push_back(std::move(spec));
    } else {
      FXL_LOG(ERROR) << "Unrecognized measurement type: " << type;
      return false;
    }

    counter++;
  }
  *spec = std::move(result);
  return true;
}

bool GetBufferingMode(const std::string& buffering_mode_name,
                      BufferingMode* out_mode) {
  if (buffering_mode_name == "oneshot") {
    *out_mode = BufferingMode::kOneshot;
  } else if (buffering_mode_name == "circular") {
    *out_mode = BufferingMode::kCircular;
  } else if (buffering_mode_name == "streaming") {
    *out_mode = BufferingMode::kStreaming;
  } else {
    return false;
  }
  return true;
}

}  // namespace tracing
