///|
fn main {
  let rules =
    #|// ===BEGIN ICANN DOMAINS===
    #|com
    #|io
    #|co.uk
    #|*.ck
    #|!www.ck
    #|// ===END ICANN DOMAINS===
    #|// ===BEGIN PRIVATE DOMAINS===
    #|github.io
    #|// ===END PRIVATE DOMAINS===
  let suffixes = @moonsuffix.SuffixList::parse(rules).unwrap()
  println("MoonSuffix compiled \{suffixes.rule_count()} rules")
  for
    domain in [
      "api.shop.example.co.uk", "www.example.com", "a.b.test.ck", "www.www.ck", "service.internal",
    ] {
    match suffixes.lookup(domain) {
      Err(error) => println("\{domain}: \{error.message()}")
      Ok(result) => {
        let registrable = match result.registrable_domain() {
          Some(value) => value
          None => ""
        }
        println(
          "\{domain}: suffix=\{result.public_suffix()} registrable=\{registrable} rule=\{result.matched_rule()}",
        )
      }
    }
  }
  let strict = suffixes
    .lookup_with_options(
      "user.github.io",
      @moonsuffix.LookupOptions::strict_icann(),
    )
    .unwrap()
  let strict_registrable = match strict.registrable_domain() {
    Some(value) => value
    None => ""
  }
  println(
    "strict ICANN user.github.io: suffix=\{strict.public_suffix()} registrable=\{strict_registrable}",
  )
  println("canonical PSL:\n\{suffixes.to_psl_text()}")
  let snapshot = suffixes.snapshot("example-rules-v1")
  println("snapshot manifest:\n\{snapshot.manifest_text()}")
  let restored = @moonsuffix.Snapshot::restore(
    snapshot.psl_text(),
    snapshot.manifest_text(),
  ).unwrap()
  println("verified snapshot revision: \{restored.source_revision()}")
  let updated_rules =
    #|// ===BEGIN ICANN DOMAINS===
    #|com
    #|io
    #|net
    #|co.uk
    #|*.ck
    #|!www.ck
    #|github.io
    #|// ===END ICANN DOMAINS===
  let updated = @moonsuffix.SuffixList::parse(updated_rules)
    .unwrap()
    .snapshot("example-rules-v2")
  println("snapshot diff:\n\{snapshot.diff(updated).report_text()}")
  let impact = snapshot.analyze_impact(
    updated,
    ["user.github.io", "api.net", "api.example.com"],
    @moonsuffix.LookupOptions::strict_icann(),
  )
  println("snapshot impact CSV:\n\{impact.to_csv()}")
  let audit = suffixes.lookup_batch_with_options(
    ["api.example.com", "service.internal", "a..com"],
    @moonsuffix.LookupOptions::strict_icann(),
  )
  println("batch CSV:\n\{audit.to_csv()}")
  let related = suffixes
    .same_registrable_site("www.example.com", "api.example.com.")
    .unwrap()
  println("same registrable site: \{related}")
  let https_site = suffixes
    .schemeful_site("https", "api.shop.example.com")
    .unwrap()
  let http_site = suffixes.schemeful_site("http", "www.example.com").unwrap()
  println("schemeful site: \{https_site.key()}")
  println("HTTP and HTTPS same-site: \{https_site.same_site(http_site)}")
  let conformance = suffixes
    .verify_psl_test_file(
      (
        #|checkPublicSuffix('example.com', 'example.com');
        #|checkPublicSuffix('a.b.test.ck', 'b.test.ck');
        #|checkPublicSuffix('.com', null);
      ),
    )
    .unwrap()
  println(
    "conformance: \{conformance.passed_count()}/\{conformance.total_count()} passed",
  )
  let policy_impact = suffixes.analyze_policy_impact(
    ["user.github.io", "service.internal", "api.example.com"],
    @moonsuffix.LookupOptions::browser_default(),
    @moonsuffix.LookupOptions::strict_icann(),
  )
  println(
    "strict-policy changes: \{policy_impact.changed_count()}/\{policy_impact.scanned_count()}",
  )
  let coverage = suffixes.analyze_rule_coverage(
    ["api.example.com", "www.www.ck", "service.internal"],
    @moonsuffix.LookupOptions::browser_default(),
  )
  println(
    "observed PSL rules: \{coverage.observed_rule_count()}/\{coverage.entries().length()}",
  )
  let cookie_scope = suffixes
    .resolve_cookie_scope("api.shop.example.com", Some(".example.com"))
    .unwrap()
  println(
    "cookie scope: domain=\{cookie_scope.domain()} host-only=\{cookie_scope.is_host_only()}",
  )
  let shareable = suffixes
    .shareable_cookie_scopes("api.shop.example.com")
    .unwrap()
  println("shareable Cookie domains: \{shareable.length()}")
  for scope in shareable {
    println("  Domain=\{scope.domain()}")
  }
}