ruleset io.picolabs.google_signin {
  meta {
    shares __testing
  }
  global {
    __testing = { "queries":
      [ { "name": "__testing" }
      //, { "name": "entry", "args": [ "key" ] }
      ] , "events":
      [ //{ "domain": "d1", "type": "t1" }
      //, { "domain": "d2", "type": "t2", "attrs": [ "a1", "a2" ] }
      ]
    }

    DID_Policy = {
        "name": "only allow google owner_did_requested events",
        "event": {
            "allow": [
                { "domain": "google", "type": "owner_did_requested"}
            ]
        }
    }

    APPLICATION_ID = "548552688547-i40k0nigeafm0vjnqgmoj2oldddgbjqi.apps.googleusercontent.com"

  }

  rule createRootDID {
    select when wrangler ruleset_added where rids >< meta:rid
    every{
      engine:newPolicy(DID_Policy) setting(registered_policy)
      engine:newChannel(name="google", type="signin", policy_id = registered_policy{"id"})
    }
  }

  rule validateIDToken {
    select when google owner_did_requested
    pre {
      id_token = event:attr("id_token");
      profile = event:attr("profile").decode();
      resp = id_token => http:get("https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=" + id_token) | "";
      valid_code = resp{"status_code"} == 200;
      content = resp{"content"}.decode();
    }
    //still need to validate the "aud" attribute and make sure this validated token was meant for our application, and is not some token id for a different app...
    if id_token && valid_code && content{"aud"} == APPLICATION_ID then
       noop()
    fired {
      raise google event "validation_success"
        attributes event:attrs.put({ "resp_content": content }).put({"profile":profile})
    }else {
      raise google event "validation_failure"
        attributes event:attrs
    }
  }

  //we need to raise the owner eci_requested in the account_management ruleset
  rule signalForOwnerID {
    select when google validation_success
    pre {
      account_id = event:attr("resp_content"){"sub"}; //not really sure why google called it sub...
    }
    if account_id then
      noop()
    fired {
      raise owner event "eci_requested"
        attributes event:attrs.put({
          "owner_id": account_id,
          "request_type": "google_signin"
        })
    }
  }

  rule generateOwnerDID {
    select when owner login_attempt where event:attr("request_type") == "google_signin"
    pre {
      pico_id = event:attr("eci") => engine:getPicoIDByECI(event:attr("eci").klog("eci"))
               | null;
    }
    if pico_id then every {
      engine:newChannel(pico_id, time:now(), "google_signin") setting(new_channel);
      event:send({"eci":new_channel{"id"}, "domain":"profile", "type":"google_profile_save", "attrs":{"profile":event:attr("profile")}})
      send_directive("Returning google_signin DID", {"DID": new_channel{"id"}});
    }
    fired {
      // schedule owner event "authenticate_channel_expired" at time:add(time:now(), {"minutes": 1})
      //   attributes {"eci": new_channel{"id"}};
    }
  }

  rule manifoldPicoChannelExpiration {
    select when owner authenticate_channel_expired
    pre {
      channel = event:attr("eci")
    }
    if channel then engine:removeChannel(channel)
  }

  rule requestNewOwnerPico {
    select when owner no_such_owner_id where event:attr("request_type") == "google_signin"
    pre {
      account_id = event:attr("resp_content"){"sub"}; //not really sure why google called it sub...
    }
    always {
      raise owner event "creation"
        attributes {
          "method": "did",
          "name": account_id,
          "rids": "io.picolabs.manifold_owner;io.picolabs.profile"
        }
    }
  }
}
