text: #pragma once
  
  #include <cstdint>
  #include <nlohmann/json.hpp>
  #include <algorithm>
  
  struct VideoConfig{
      enum class RateCtrlMode{
          CBR,
          VBR
      } rateCtrlMode;
      
      enum class Profile{
          H264_BASELINE,
          H264_MAIN,
          H264_HIGH,
          H265_MAIN,
          MJPEG
      } profile;
  
      int bitrate, maxBitrate; //bps
      int keyframeFrequency; //every x number of frames a keyframe is inserted
      int numBFrames; 
      int quality; //0-100
  
      nlohmann::json toJson(){
          
          nlohmann::json obj;
  
          obj["rateCtrlMode"] = (int) rateCtrlMode;
          obj["profile"] = (int) profile;
  
          obj["bitrate"] = bitrate;
          obj["maxBitrate"] = maxBitrate;
          obj["keyframeFrequency"] = keyframeFrequency;
          obj["numBFrames"] = numBFrames;
          obj["quality"] = quality;
  
          return obj;
  
      }
  
      static VideoConfig fromJson(nlohmann::json obj){
          
          VideoConfig config = {};
  
          //Check if rateCtrlMode is string or int
          if(obj.count("rateCtrlMode") > 0){
              if(obj["rateCtrlMode"].is_string()){
                  auto mode = obj["rateCtrlMode"].get<std::string>();
                  std::transform(mode.begin(), mode.end(), mode.begin(), ::tolower);
  
                  if(mode == "cbr"){
                      config.rateCtrlMode = RateCtrlMode::CBR;
                  } else if(mode == "vbr"){
                      config.rateCtrlMode = RateCtrlMode::VBR;
                  }
              } else if(obj["rateCtrlMode"].is_number_integer()){
                  config.rateCtrlMode = (RateCtrlMode) obj["rateCtrlMode"].get<int>();
              }
          }
          if(obj.count("profile") > 0){
              if(obj["profile"].is_string()){
                  auto profile = obj["profile"].get<std::string>();
                  std::transform(profile.begin(), profile.end(), profile.begin(), ::tolower);
                  
                  if(profile == "h264_baseline"){
                      config.profile = Profile::H264_BASELINE;
                  } else if(profile == "h264_main"){
                      config.profile = Profile::H264_MAIN;
                  } else if(profile == "h264_high"){
                      config.profile = Profile::H264_HIGH;
                  } else if(profile == "h265_main"){
                      config.profile = Profile::H265_MAIN;
                  } else if(profile == "mjpeg"){
                      config.profile = Profile::MJPEG;
                  }
              } else if(obj["profile"].is_number_integer()){
                  config.profile = (Profile) obj["profile"].get<int>();
              }
          }
  
  
          if(obj.count("bitrate") > 0){
              config.bitrate = obj["bitrate"].get<int>();
          }
          if(obj.count("maxBitrate") > 0){
              config.maxBitrate = obj["maxBitrate"].get<int>();
          }
          if(obj.count("keyframeFrequency") > 0){
              config.keyframeFrequency = obj["keyframeFrequency"].get<int>();
          }
          if(obj.count("numBFrames") > 0){
              config.numBFrames = obj["numBFrames"].get<int>();
          }
          if(obj.count("quality") > 0){
              config.quality = obj["quality"].get<int>();
          }
  
          return config;
      }
  
  };
  