///|
pub struct HarNameValue {
  name_value : String
  value_value : String
  comment_value : String?
} derive(Eq, Debug)

///|
pub fn HarNameValue::new(
  name : String,
  value : String,
  comment? : String,
) -> HarNameValue {
  { name_value: name, value_value: value, comment_value: comment }
}

///|
pub fn HarNameValue::name(self : HarNameValue) -> String {
  self.name_value
}

///|
pub fn HarNameValue::value(self : HarNameValue) -> String {
  self.value_value
}

///|
pub fn HarNameValue::comment(self : HarNameValue) -> String? {
  self.comment_value
}

///|
pub fn HarNameValue::name_equals(
  self : HarNameValue,
  expected : String,
) -> Bool {
  self.name_value.to_lower() == expected.to_lower()
}

///|
fn parse_name_value_cursor(
  cursor : JsonCursor,
) -> Result[HarNameValue, HarError] {
  let name = match cursor.required_string("name") {
    Ok(value) => value
    Err(error) => return Err(error)
  }
  let value = match cursor.required_string("value") {
    Ok(value) => value
    Err(error) => return Err(error)
  }
  let comment = match cursor.optional_string("comment") {
    Ok(value) => value
    Err(error) => return Err(error)
  }
  Ok({ name_value: name, value_value: value, comment_value: comment })
}

///|
fn parse_name_value_array(
  cursors : Array[JsonCursor],
) -> Result[Array[HarNameValue], HarError] {
  let values : Array[HarNameValue] = []
  for cursor in cursors {
    match parse_name_value_cursor(cursor) {
      Ok(value) => values.push(value)
      Err(error) => return Err(error)
    }
  }
  Ok(values)
}

///|
pub fn parse_name_values(
  input : String,
) -> Result[Array[HarNameValue], HarError] {
  let cursor = match parse_json_cursor(input) {
    Ok(value) => value
    Err(error) => return Err(error)
  }
  let cursors = match cursor.to_cursor_array() {
    Ok(value) => value
    Err(error) => return Err(error)
  }
  parse_name_value_array(cursors)
}

///|
pub struct HarCookie {
  name_value : String
  value_value : String
  path_value : String?
  domain_value : String?
  expires_value : String?
  http_only_value : Bool?
  secure_value : Bool?
  comment_value : String?
} derive(Eq, Debug)

///|
pub fn HarCookie::new(
  name : String,
  value : String,
  path? : String,
  domain? : String,
  expires? : String,
  http_only? : Bool,
  secure? : Bool,
  comment? : String,
) -> HarCookie {
  {
    name_value: name,
    value_value: value,
    path_value: path,
    domain_value: domain,
    expires_value: expires,
    http_only_value: http_only,
    secure_value: secure,
    comment_value: comment,
  }
}

///|
pub fn HarCookie::name(self : HarCookie) -> String {
  self.name_value
}

///|
pub fn HarCookie::value(self : HarCookie) -> String {
  self.value_value
}

///|
pub fn HarCookie::path(self : HarCookie) -> String? {
  self.path_value
}

///|
pub fn HarCookie::domain(self : HarCookie) -> String? {
  self.domain_value
}

///|
pub fn HarCookie::expires(self : HarCookie) -> String? {
  self.expires_value
}

///|
pub fn HarCookie::http_only(self : HarCookie) -> Bool? {
  self.http_only_value
}

///|
pub fn HarCookie::secure(self : HarCookie) -> Bool? {
  self.secure_value
}

///|
pub fn HarCookie::comment(self : HarCookie) -> String? {
  self.comment_value
}

///|
fn parse_cookie_cursor(cursor : JsonCursor) -> Result[HarCookie, HarError] {
  let name = match cursor.required_string("name") {
    Ok(value) => value
    Err(error) => return Err(error)
  }
  let value = match cursor.required_string("value") {
    Ok(value) => value
    Err(error) => return Err(error)
  }
  let path = match cursor.optional_string("path") {
    Ok(value) => value
    Err(error) => return Err(error)
  }
  let domain = match cursor.optional_string("domain") {
    Ok(value) => value
    Err(error) => return Err(error)
  }
  let expires = match cursor.optional_string("expires") {
    Ok(value) => value
    Err(error) => return Err(error)
  }
  let http_only = match cursor.optional_bool("httpOnly") {
    Ok(value) => value
    Err(error) => return Err(error)
  }
  let secure = match cursor.optional_bool("secure") {
    Ok(value) => value
    Err(error) => return Err(error)
  }
  let comment = match cursor.optional_string("comment") {
    Ok(value) => value
    Err(error) => return Err(error)
  }
  Ok({
    name_value: name,
    value_value: value,
    path_value: path,
    domain_value: domain,
    expires_value: expires,
    http_only_value: http_only,
    secure_value: secure,
    comment_value: comment,
  })
}

///|
fn parse_cookie_array(
  cursors : Array[JsonCursor],
) -> Result[Array[HarCookie], HarError] {
  let values : Array[HarCookie] = []
  for cursor in cursors {
    match parse_cookie_cursor(cursor) {
      Ok(value) => values.push(value)
      Err(error) => return Err(error)
    }
  }
  Ok(values)
}

///|
pub fn parse_cookies(input : String) -> Result[Array[HarCookie], HarError] {
  let cursor = match parse_json_cursor(input) {
    Ok(value) => value
    Err(error) => return Err(error)
  }
  let cursors = match cursor.to_cursor_array() {
    Ok(value) => value
    Err(error) => return Err(error)
  }
  parse_cookie_array(cursors)
}

///|
pub struct HarPostParam {
  name_value : String
  value_value : String?
  file_name_value : String?
  content_type_value : String?
  comment_value : String?
} derive(Eq, Debug)

///|
pub fn HarPostParam::new(
  name : String,
  value? : String,
  file_name? : String,
  content_type? : String,
  comment? : String,
) -> HarPostParam {
  {
    name_value: name,
    value_value: value,
    file_name_value: file_name,
    content_type_value: content_type,
    comment_value: comment,
  }
}

///|
pub fn HarPostParam::name(self : HarPostParam) -> String {
  self.name_value
}

///|
pub fn HarPostParam::value(self : HarPostParam) -> String? {
  self.value_value
}

///|
pub fn HarPostParam::file_name(self : HarPostParam) -> String? {
  self.file_name_value
}

///|
pub fn HarPostParam::content_type(self : HarPostParam) -> String? {
  self.content_type_value
}

///|
pub fn HarPostParam::comment(self : HarPostParam) -> String? {
  self.comment_value
}

///|
fn parse_post_param_cursor(
  cursor : JsonCursor,
) -> Result[HarPostParam, HarError] {
  let name = match cursor.required_string("name") {
    Ok(value) => value
    Err(error) => return Err(error)
  }
  let value = match cursor.optional_string("value") {
    Ok(value) => value
    Err(error) => return Err(error)
  }
  let file_name = match cursor.optional_string("fileName") {
    Ok(value) => value
    Err(error) => return Err(error)
  }
  let content_type = match cursor.optional_string("contentType") {
    Ok(value) => value
    Err(error) => return Err(error)
  }
  let comment = match cursor.optional_string("comment") {
    Ok(value) => value
    Err(error) => return Err(error)
  }
  Ok({
    name_value: name,
    value_value: value,
    file_name_value: file_name,
    content_type_value: content_type,
    comment_value: comment,
  })
}

///|
pub struct HarPostData {
  mime_type_value : String
  params_value : Array[HarPostParam]
  text_value : String?
  comment_value : String?
} derive(Eq, Debug)

///|
pub fn HarPostData::new(
  mime_type : String,
  params? : Array[HarPostParam],
  text? : String,
  comment? : String,
) -> HarPostData {
  {
    mime_type_value: mime_type,
    params_value: match params {
      Some(value) => value
      None => []
    },
    text_value: text,
    comment_value: comment,
  }
}

///|
pub fn HarPostData::mime_type(self : HarPostData) -> String {
  self.mime_type_value
}

///|
pub fn HarPostData::params(self : HarPostData) -> Array[HarPostParam] {
  self.params_value.copy()
}

///|
pub fn HarPostData::text(self : HarPostData) -> String? {
  self.text_value
}

///|
pub fn HarPostData::comment(self : HarPostData) -> String? {
  self.comment_value
}

///|
pub fn HarPostData::is_multipart(self : HarPostData) -> Bool {
  self.mime_type_value.to_lower().contains("multipart/")
}

///|
pub fn HarPostData::is_form_urlencoded(self : HarPostData) -> Bool {
  self.mime_type_value.to_lower().contains("application/x-www-form-urlencoded")
}

///|
fn parse_post_data_cursor(cursor : JsonCursor) -> Result[HarPostData, HarError] {
  let mime_type = match cursor.required_string("mimeType") {
    Ok(value) => value
    Err(error) => return Err(error)
  }
  let param_cursors = match cursor.optional_array("params") {
    Ok(value) => value
    Err(error) => return Err(error)
  }
  let params : Array[HarPostParam] = []
  for param_cursor in param_cursors {
    match parse_post_param_cursor(param_cursor) {
      Ok(value) => params.push(value)
      Err(error) => return Err(error)
    }
  }
  let text = match cursor.optional_string("text") {
    Ok(value) => value
    Err(error) => return Err(error)
  }
  let comment = match cursor.optional_string("comment") {
    Ok(value) => value
    Err(error) => return Err(error)
  }
  Ok({
    mime_type_value: mime_type,
    params_value: params,
    text_value: text,
    comment_value: comment,
  })
}

///|
pub fn parse_post_data(input : String) -> Result[HarPostData, HarError] {
  let cursor = match parse_json_cursor(input) {
    Ok(value) => value
    Err(error) => return Err(error)
  }
  parse_post_data_cursor(cursor)
}