package TestCase::Lib::SPVM::HTTP::URL {
  use SPVM::HTTP::URL;

  sub test_parse_escape_all : int () {
    my $p_raw = "abc";
    my $p_escaped = "abc";
    my $p_raw_2 = "d";
    my $p_escaped_2 = "d";
    my $q_raw = "尾骶骨𠮷 🤔";
    my $q_escaped = "%E5%B0%BE%E9%AA%B6%E9%AA%A8%F0%A0%AE%B7%20%F0%9F%A4%94";
    my $fragment_raw = "🤔 𠮷尾骶骨";
    my $fragment_escaped = "%F0%9F%A4%94%20%F0%A0%AE%B7%E5%B0%BE%E9%AA%B6%E9%AA%A8";
    my $url = SPVM::HTTP::URL->parse(
      "http://www.example.com:8888/blog/posts?q=$q_escaped&p=$p_escaped&p=$p_escaped_2#$fragment_escaped");
    {
      my $got = $url->to_str();
      my $expected = "http://www.example.com:8888/blog/posts?q=$q_escaped&p=$p_escaped&p=$p_escaped_2#$fragment_escaped";
      unless ($url->to_str() eq $expected) {
        warn("     got: '$got'\nexpected: '$expected'");
        return 0;
      }
    }
    unless ($url->{scheme} eq "http") {
      return 0;
    }
    unless ($url->{host} eq "www.example.com") {
      return 0;
    }
    unless ($url->{port} == 8888) {
      return 0;
    }
    unless ($url->{path} eq "/blog/posts") {
      return 0;
    }
    unless ($url->has_trailing_slash == 0) {
      return 0;
    }
    unless ((string)($url->{params}->get("p")) eq $p_raw) {
      return 0;
    }
    my $multi_p = $url->{params}->get_multi("p");
    unless (@$multi_p == 2 &&
        $multi_p->[0] eq $p_raw && $multi_p->[1] eq $p_raw_2) {
      return 0;
    }
    unless ((string)($url->{params}->get("q")) eq $q_raw) {
      return 0;
    }
    unless ((string)($url->{fragment} eq $fragment_raw)) {
      return 0;
    }
    return 1;
  }

  sub test_parse_host : int () {
    my $url = SPVM::HTTP::URL->parse("https://host");
    unless ($url->{scheme} eq "https") {
      return 0;
    }
    unless ($url->{host} eq "host") {
      return 0;
    }
    return 1;
  }

  sub test_parse_host_path : int () {
    {
      my $url = SPVM::HTTP::URL->parse("https://host/path");
      unless ($url->{scheme} eq "https") {
        return 0;
      }
      unless ($url->{host} eq "host") {
        return 0;
      }
      unless ($url->{path} eq "/path") {
        return 0;
      }
    }
    {
      my $url = SPVM::HTTP::URL->parse("https://host/path/hoge/fuga//");
      unless ($url->{scheme} eq "https") {
        return 0;
      }
      unless ($url->{host} eq "host") {
        return 0;
      }
      unless ($url->{path} eq "/path/hoge/fuga//") {
        return 0;
      }
    }
    return 1;
  }

  sub test_parse_host_params : int () {
    my $url = SPVM::HTTP::URL->parse("https://host?abc=%E5%B0%BE%E9%AA%B6%E9%AA%A8%F0%A0%AE%B7%20%F0%9F%A4%94");
    unless ($url->{scheme} eq "https") {
      return 0;
    }
    unless ($url->{host} eq "host") {
      return 0;
    }
    unless ($url->{params}->get("abc") eq "尾骶骨𠮷 🤔") {
      return 0;
    }
    return 1;
  }

  sub test_parse_host_fragment : int () {
    my $url = SPVM::HTTP::URL->parse("https://host#%E5%B0%BE%E9%AA%B6%E9%AA%A8%F0%A0%AE%B7%20%F0%9F%A4%94");
    unless ($url->{scheme} eq "https") {
      return 0;
    }
    unless ($url->{host} eq "host") {
      return 0;
    }
    unless ($url->{fragment} eq "尾骶骨𠮷 🤔") {
      return 0;
    }
    return 1;
  }

  sub test_parse_host_path_fragment : int () {
    my $url = SPVM::HTTP::URL->parse("https://host/blog/posts#%E5%B0%BE%E9%AA%B6%E9%AA%A8%F0%A0%AE%B7%20%F0%9F%A4%94");
    unless ($url->{scheme} eq "https") {
      return 0;
    }
    unless ($url->{host} eq "host") {
      return 0;
    }
    unless ($url->{path} eq "/blog/posts") {
      return 0;
    }
    unless ($url->{fragment} eq "尾骶骨𠮷 🤔") {
      return 0;
    }
    return 1;
  }

  sub test_not_found_scheme_separator : int () {
    eval {
      SPVM::HTTP::URL->parse("http//www.example.com");
    };
    unless ($@) {
      return 0;
    }
    $@ = undef;
    return 1;
  }

  sub test_amazon_path_escaped : int () {
    my $url = SPVM::HTTP::URL->parse("https://www.amazon.co.jp/%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%A9%E2%80%95%E5%8E%9F%E7%90%86%E3%83%BB%E6%8A%80%E6%B3%95%E3%83%BB%E3%83%84%E3%83%BC%E3%83%AB%E3%80%882%E3%80%89-Information-Computing-V-%E3%82%A8%E3%82%A4%E3%83%9B/dp/4781905862/ref=sr_1_22?ie=UTF8&qid=1552415136&sr=8-22&keywords=%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%A9#%E5%95%86%E5%93%81%E3%81%AE%E8%AA%AC%E6%98%8E");
    unless ($url->{scheme} eq "https") {
      return 0;
    }
    unless ($url->{host} eq "www.amazon.co.jp") {
      return 0;
    }
    unless ($url->{path} eq "/コンパイラ―原理・技法・ツール〈2〉-Information-Computing-V-エイホ/dp/4781905862/ref=sr_1_22") {
      return 0;
    }
    my $keys = $url->{params}->keys;
    unless (@$keys == 4) {
      return 0;
    }
    for (my $i = 0; $i < @$keys; ++$i) {
      my $key = $keys->[$i];
      my $val = $url->{params}->get($key);
      if ($key eq "ie") {
        unless ($val eq "UTF8") {
          return 0;
        }
      }
      if ($key eq "keywords") {
        unless ($val eq "コンパイラ") {
          return 0;
        }
      }
      if ($key eq "qid") {
        unless ($val eq "1552415136") {
          return 0;
        }
      }
      if ($key eq "sr") {
        unless ($val eq "8-22") {
          return 0;
        }
      }
    }
    unless ($url->{fragment} eq "商品の説明") {
      return 0;
    }
    return 1;
  }

  sub test_host_is_not_for_url : int () {
    eval {
      SPVM::HTTP::URL->parse("javascript:alert(\"hello%20world\");");
    };
    unless ($@) {
      return 0;
    }
    $@ = undef;
    return 1;
  }

  sub test_trailing_slash : int () {
    my $tests = [
      [
        ["http://www.example.com", "http://www.example.com/"],
        ["", "/"],
      ],
      [
        ["http://www.google.com?q=spvm", "http://www.google.com/?q=spvm"],
        ["", "/"],
      ],
      [
        ["http://www.blog.com/posts", "http://www.blog.com/posts/"],
        ["/posts", "/posts/"],
      ],
      [
        ["http://www.blog.com/posts?p=spvm", "http://www.blog.com/posts/?p=spvm"],
        ["/posts", "/posts/"],
      ]
    ];
    for (my $i = 0; $i < @$tests; ++$i) {
      my $test_url = $tests->[$i]->[0];
      my $test_path = $tests->[$i]->[1];
      my $url = SPVM::HTTP::URL->parse($test_url->[0]);
      unless ($url->has_trailing_slash == 0 &&
          $url->{path} eq $test_path->[0] &&
          $url->to_str eq $test_url->[0]) {
        return 0;
      }
      $url->enable_trailing_slash;
      unless ($url->has_trailing_slash == 1 &&
          $url->{path} eq $test_path->[1] &&
          $url->to_str eq $test_url->[1]) {
        return 0;
      }
      $url->enable_trailing_slash;
      unless ($url->has_trailing_slash == 1 &&
          $url->{path} eq $test_path->[1] &&
          $url->to_str eq $test_url->[1]) {
        return 0;
      }
      $url->disable_trailing_slash;
      unless ($url->has_trailing_slash == 0 &&
          $url->{path} eq $test_path->[0] &&
          $url->to_str eq $test_url->[0]) {
        return 0;
      }
      $url->disable_trailing_slash;
      unless ($url->has_trailing_slash == 0 &&
          $url->{path} eq $test_path->[0] &&
          $url->to_str eq $test_url->[0]) {
        return 0;
      }
    }
    return 1;
  }
}
