import dw::core::URL
import dw::core::Assertions

fun checkIdentity(decoded: String, encoded: String, encoder: (String) -> String, decoder: (String) -> String): Boolean =
[
  Assertions::mustEqual(
    'Enc' ++ encoder(decoded),
    'Enc' ++ encoded
  ),
  Assertions::mustEqual(
    'Dec' ++ decoder(encoded),
    'Dec' ++ decoded
  ),
  Assertions::mustEqual(decoded, decoder(encoder(decoded))),
] reduce ($ and $$)
---
[
  Assertions::mustEqual(
    URL::compose `http://asd/$(' texto a encodear ')/texto a encodear`,
    'http://asd/%20texto%20a%20encodear%20/texto a encodear'
  ),

  Assertions::mustEqual(
    URL::compose `http://asd/$('Алексей')/Алексей`,
    'http://asd/%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B5%D0%B9/Алексей'
  ),

  checkIdentity(
    "Алексей",
    "%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B5%D0%B9",
    URL::encodeURIComponent,
    URL::decodeURIComponent
  ),

  checkIdentity(
    "Björk Guðmundsdóttir",
    "Bj%C3%B6rk%20Gu%C3%B0mundsd%C3%B3ttir",
    URL::encodeURIComponent,
    URL::decodeURIComponent
  ),

  checkIdentity(
    "A~!@#\$%^&*()=+[]{}\\;:'\",/?",
    "A~!%40%23%24%25%5E%26*()%3D%2B%5B%5D%7B%7D%5C%3B%3A'%22%2C%2F%3F",
    URL::encodeURIComponent,
    URL::decodeURIComponent
  ),

  checkIdentity(
    "B~!@#\$%^&*()=+[]{}\\;:'\",/?\$",
    "B~!@#\$%25%5E&*()=%2B%5B%5D%7B%7D%5C;:'%22,/?\$",
    URL::encodeURI,
    URL::decodeURI
  ),

  checkIdentity(
    'C;,/?:@&=+\$-_.!~*\'().# \t',
    'C;,/?:@&=%2B\$-_.!~*\'().#%20%09',
    URL::encodeURI,
    URL::decodeURI
  ),

  checkIdentity(
    'D;,/?:@&=+\$-_.!~*\'().# \t',
    "D%3B%2C%2F%3F%3A%40%26%3D%2B%24-_.!~*'().%23%20%09",
    URL::encodeURIComponent,
    URL::decodeURIComponent
  ),

  checkIdentity(
    "https://w3schools.com/my test.asp?name=ståle&car=saab",
    "https%3A%2F%2Fw3schools.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab",
    URL::encodeURIComponent,
    URL::decodeURIComponent
  ),

  checkIdentity(
    "https://w3schools.com/my test.asp?name=ståle&car=saab)@#*&(\$YUIPHRJK“…≥æß∂å≥ßµ∂å∫ßˆ•§¡™£",
    "https%3A%2F%2Fw3schools.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab)%40%23*%26(%24YUIPHRJK%E2%80%9C%E2%80%A6%E2%89%A5%C3%A6%C3%9F%E2%88%82%C3%A5%E2%89%A5%C3%9F%C2%B5%E2%88%82%C3%A5%E2%88%AB%C3%9F%CB%86%E2%80%A2%C2%A7%C2%A1%E2%84%A2%C2%A3",
    URL::encodeURIComponent,
    URL::decodeURIComponent
  ),


  checkIdentity(
    "my test.asp?name=ståle&car=saab",
    "my%20test.asp?name=st%C3%A5le&car=saab",
    URL::encodeURI,
    URL::decodeURI
  ),

  Assertions::mustEqual(
    URL::parseURI('http://asd:dasd@my-domain.local:1234/asdn/my%20name?kv=1&kv=2&k3#dsa'),
    {
      isValid: true,
      raw: "http://asd:dasd@my-domain.local:1234/asdn/my%20name?kv=1&kv=2&k3#dsa",
      host: "my-domain.local",
      authority: "asd:dasd@my-domain.local:1234",
      fragment: "dsa",
      path: "/asdn/my name",
      port: 1234,
      query: "kv=1&kv=2&k3",
      scheme: "http",
      user: "asd:dasd",
      isAbsolute: true,
      isOpaque: false
    }
  )
] reduce ($$ and $)