<commit_before>
// varibles 
// ent:my_picos


// operators are camel case, variables are snake case.


// questions
// when should we use klogs? what is the standard? varible getters|| mutators 
// is log our choice of status setting for rules ? when should we send directives. can we send directives in postlude with status varible?
// varible validating for removing , deleteing, uninstalling
// when registering a ruleset if you pass empty peramiters what happens

//old channel create uses a "login" eci to create a new channel, why and should we do it that way? 

//whats the benifit of forking a ruleset vs creating a new one?
//pci: lacks abillity to change channel type 

ruleset b507199x5 {
  meta {
    name "nano_manager"
    description <<
      Nano Manager ( ) Module

      use module a169x625 alias nano_manager

      This Ruleset/Module provides a developer interface to the PICO (persistent computer object).
      When a PICO is created or authenticated this ruleset
      will be installed into the Personal Cloud to provide an Event layer.
    >>
    author "BYUPICOLab"
    
    logging off

    use module b16x24 alias system_credentials
    // errors raised to.... unknown

    // Accounting keys
      //none
    provides registered, singleRuleset, installed, describeRules, //ruleset
    channels, attributes, policy, type, //channel
    apps, get_app,type,/*testing*/list_bootstrap, get_appinfo, list_callback, //apps
    accountProfile, children, parent, attributes, //pico
    schedules, scheduleHistory, // schedule
    subscriptions, outGoing, incoming //subscription
    sharing on

  }

  //dispatch {
    //domain "ktest.heroku.com"
  //}
  global {
    //functions
	
	
  //-------------------- Rulesets --------------------
    registered = function() {
      eci = meta:eci();
        rulesets = rsm:list_rulesets(eci).defaultsTo({},standardError("undefined"));
        ruleset_gallery = rulesets.map( function(rid){
          ridInfo = rsm:get_ruleset( rid ).defaultsTo({},standardError("undefined"));
          ridInfo
        }).defaultsTo("error",standardError("undefined"));
        {
          'status' : (ruleset_gallery neq "error"),
          'rulesets' : ruleset_gallery          
        };
    }
    singleRuleset = function(rid) { 
      eci = meta:eci();
      results = registered().defaultsTo({},standardError("undefined"));
      rulesets = results{"rulesets"}.defaultsTo({},standardError("undefined"));
      result = rulesets.filter( function(rule_set){rule_set{"rid"} eq rid } ).defaultsTo( "error",standardError("undefined"));
      {
        'status' : (result neq "error"),
        'ruleset' : result[0]
      };
    }
    installed = function() {
      eci = meta:eci().klog("eci: ");
      results = pci:list_ruleset(eci).klog("results of pci list_ruleset");//defaultsTo("error",standardError("pci list_ruleset failed"));  
      rids = results{'rids'}.defaultsTo("error",standardError("no hash key rids"));
      {
       'status'   : (rids neq "error"),
        'rids'     : rids
      };
    }
    describeRules = function(rids) {//takes an array of rids as parameter // can we write this better???????
      rids_string = rids.join(";");
      describe_url = "https://#{meta:host()}/ruleset/describe/#{$rids_string}";
      resp = http:get(describe_url);
      results = resp{"content"}.decode().defaultsTo("",standardError("content failed to return"));
      {
       'status'   : (resp{"status_code"} eq "200"),
       'description'     : results
      };
    }
    install = defaction(eci, ridlist){
      new_ruleset = pci:new_ruleset(eci, ridlist);
      send_directive("installed #{ridlist}");
    }
    uninstall = defaction(eci, ridlist){
      deleted = pci:delete_ruleset(eci, ridlist);
      send_directive("uninstalled #{ridlist}");
    }
  //-------------------- Channels --------------------
    channels = function() { 
      eci = meta:eci();
      results = pci:list_eci(eci).defaultsTo({},standardError("undefined")); // list of ECIs assigned to userid
      channels = results{'channels'}.defaultsTo("error",standardError("undefined")); // list of channels if list_eci request was valid
      {
        'status'   : (channels neq "error"),
        'channels' : channels
      };
    }
    attributes = function(eci) {
      results = pci:get_eci_attributes(eci).defaultsTo("error",standardError("undefined")); // list of ECIs assigned to userid
      {
        'status'   : (results neq "error"),
        'Attributes' : results
      };
    }
    policy = function(eci) {
      results = pci:get_eci_policy(eci).defaultsTo("error",standardError("undefined")); // list of ECIs assigned to userid
      {
        'status'   : (results neq "error"),
        'Policy' : results
      };
    }
    type = function(channel_id) { // untested!!!!!!!!!!!!!!!!!!!
      channels = Channels().defaultsTo("error",">> undefined >>");

    getType = function(channel_id,channels) {
        channels = channels{"channels"}.defaultsTo("undefined",standardError("undefined"));
        channel = channels.filter( function(channel){channel{"cid"} eq channel_id } ).defaultsTo( "error",standardError("undefined"));
        chan = channel[0];
        type = chan{"type"};
        temp = (type.typeof() eq "str" ) => type | type.typeof() eq "array" => type[0] |  type.keys();
        type2 = (temp.typeof() eq "array") => temp[0] | temp;   
        type2;
      };
      type = ((channels neq "error") && (channels neq {} )) => getType() | "error";
      {
        'status'   : (type neq "error"),
        'channels' : channels
      };
    }
    updateAttrs = defaction(channel_id, attributes){
      set_eci = pci:set_eci_attributes(channel_id, attributes);
      send_directive("updated #{channel_id} attributes");
    }
    updatePolicy = defaction(channel_id, policy){
      set_polcy = pci:set_eci_policy(channel_id, policy); // policy needs to be a map, do we need to cast types?
      send_directive("updated #{channel_id} policy");
    }
    deleteEci = defaction(channelID) {
      deleteeci =pci:delete_eci(channelID);
      send_directive("deleted #{channelID}");
    }
    createEci = defaction(user, options){
      new_eci = pci:new_eci(user, options);
      send_directive("created new eci");
    }
  //-------------------- Apps --------------------
    apps = function() { 
      eci = meta:eci();
      apps = pci:list_apps(eci).defaultsTo("error",standardError("undefined"));
      {
        'status' : (apps neq "error"),
        'apps' : apps
      }
    }    
    get_app = function(appECI){
      apps = apps().defaultsTo("error",standardError("apps"));
      app = apps{appECI}.defaultsTo("error",standardError("app"));
     // app = (apps{appECI}).delete(["appSecret"]).defaultsTo("error",standardError("app"))
      {
        'status' : (app neq "error"),
        'app' : app
      }
    }
    list_bootstrap = function(appECI){
      pci:list_bootstrap(appECI);
    }
    get_appinfo = function(appECI){
      pci:get_appinfo(appECI);
    }
    list_callback = function(appECI){
      pci:list_callback(appECI);
    }
    addPCIbootstraps = defaction(appECI,bootstrapRids){
      boot = bootstrapRids.map(function(rid) { pci:add_bootstrap(appECI, rid); }).klog(">>>>>> bootstrap add result >>>>>>>");
      send_directive("pci bootstraps updated.")
        with rulesets = list_bootstrap(appECI); // is this working?
    }
    removePCIbootstraps = defaction(appEC,IbootstrapRids){
      boot = bootstrapRids.map(function(rid) { pci:remove_bootstrap(appECI, rid); }).klog(">>>>>> bootstrap removed result >>>>>>>");
      send_directive("pci bootstraps removed.")
        with rulesets = list_bootstrap(appECI); 
    }
    removePCIcallback = defaction(appECI,PCIcallbacks){
      PCIcallbacks =( PCIcallbacks || []).append(PCIcallbacks);
      boot = PCIcallbacks.map(function(url) { pci:remove_callback(appECI, url); }).klog(">>>>>> callback remove result >>>>>>>");
      send_directive("pci callback removed.")
        with rulesets = pci:list_callback(appECI);
    }
    update_app = defaction(app_eci,app_data,bootstrap_rids){
      //remove all 
      remove_defact = removePCIcallback(app_eci);
      remove_appinfo = pci:remove_appinfo(app_eci);
      remove_defact = removePCIbootstraps(app_eci);
      // add new 
      add_callback = pci:add_callback(app_eci, app_data{"appCallbackURL"}); 
      add_info = pci:add_appinfo(app_eci,{
        "icon": app_data{"appImageURL"},
        "name": app_data{"appName"},
        "description": app_data{"appDescription"},
        "info_url": app_data{"info_page"},
        "declined_url": app_data{"appDeclinedURL"}
      });
      addPCIbootstraps(app_eci,bootstrap_rids);
    };

		  
	//-------------------- Picos --------------------
  accountProfile = function() {
    profile = pci:get_profile(currentSession()).defaultsTo("error",standardError("undefined"))
    .put( ["oauth_eci"], meta:eci() );
    {
     'status' : (profile neq "error"),
     'profile'  : profile
    }
  }
  currentSession = function() {
    pci:session_token(meta:eci()).defaultsTo("", standardError("pci session_token failed")); // this is old way.. why not just eci??
  };

	children = function() {
		eci = meta:eci();
		children = pci:list_children(eci).defaultsTo("error", standardError("pci children list failed"));
		{
			'status' : (children neq "error"),
			'children' : children
		}
	}
	parent = function() {
		eci = meta:eci();
		parent = pci:list_parent(eci).defaultsTo("error", standardError("pci parent retrival failed"));<commit_msg>quick children on child debug change<commit_after>
// varibles 
// ent:my_picos


// operators are camel case, variables are snake case.


// questions
// when should we use klogs? what is the standard? varible getters|| mutators 
// is log our choice of status setting for rules ? when should we send directives. can we send directives in postlude with status varible?
// varible validating for removing , deleteing, uninstalling
// when registering a ruleset if you pass empty peramiters what happens

//old channel create uses a "login" eci to create a new channel, why and should we do it that way? 

//whats the benifit of forking a ruleset vs creating a new one?
//pci: lacks abillity to change channel type 

ruleset b507199x5 {
  meta {
    name "nano_manager"
    description <<
      Nano Manager ( ) Module

      use module a169x625 alias nano_manager

      This Ruleset/Module provides a developer interface to the PICO (persistent computer object).
      When a PICO is created or authenticated this ruleset
      will be installed into the Personal Cloud to provide an Event layer.
    >>
    author "BYUPICOLab"
    
    logging off

    use module b16x24 alias system_credentials
    // errors raised to.... unknown

    // Accounting keys
      //none
    provides registered, singleRuleset, installed, describeRules, //ruleset
    channels, attributes, policy, type, //channel
    apps, get_app,type,/*testing*/list_bootstrap, get_appinfo, list_callback, //apps
    accountProfile, children, parent, attributes, //pico
    schedules, scheduleHistory, // schedule
    subscriptions, outGoing, incoming //subscription
    sharing on

  }

  //dispatch {
    //domain "ktest.heroku.com"
  //}
  global {
    //functions
	
	
  //-------------------- Rulesets --------------------
    registered = function() {
      eci = meta:eci();
        rulesets = rsm:list_rulesets(eci).defaultsTo({},standardError("undefined"));
        ruleset_gallery = rulesets.map( function(rid){
          ridInfo = rsm:get_ruleset( rid ).defaultsTo({},standardError("undefined"));
          ridInfo
        }).defaultsTo("error",standardError("undefined"));
        {
          'status' : (ruleset_gallery neq "error"),
          'rulesets' : ruleset_gallery          
        };
    }
    singleRuleset = function(rid) { 
      eci = meta:eci();
      results = registered().defaultsTo({},standardError("undefined"));
      rulesets = results{"rulesets"}.defaultsTo({},standardError("undefined"));
      result = rulesets.filter( function(rule_set){rule_set{"rid"} eq rid } ).defaultsTo( "error",standardError("undefined"));
      {
        'status' : (result neq "error"),
        'ruleset' : result[0]
      };
    }
    installed = function() {
      eci = meta:eci().klog("eci: ");
      results = pci:list_ruleset(eci).klog("results of pci list_ruleset");//defaultsTo("error",standardError("pci list_ruleset failed"));  
      rids = results{'rids'}.defaultsTo("error",standardError("no hash key rids"));
      {
       'status'   : (rids neq "error"),
        'rids'     : rids
      };
    }
    describeRules = function(rids) {//takes an array of rids as parameter // can we write this better???????
      rids_string = rids.join(";");
      describe_url = "https://#{meta:host()}/ruleset/describe/#{$rids_string}";
      resp = http:get(describe_url);
      results = resp{"content"}.decode().defaultsTo("",standardError("content failed to return"));
      {
       'status'   : (resp{"status_code"} eq "200"),
       'description'     : results
      };
    }
    install = defaction(eci, ridlist){
      new_ruleset = pci:new_ruleset(eci, ridlist);
      send_directive("installed #{ridlist}");
    }
    uninstall = defaction(eci, ridlist){
      deleted = pci:delete_ruleset(eci, ridlist);
      send_directive("uninstalled #{ridlist}");
    }
  //-------------------- Channels --------------------
    channels = function() { 
      eci = meta:eci();
      results = pci:list_eci(eci).defaultsTo({},standardError("undefined")); // list of ECIs assigned to userid
      channels = results{'channels'}.defaultsTo("error",standardError("undefined")); // list of channels if list_eci request was valid
      {
        'status'   : (channels neq "error"),
        'channels' : channels
      };
    }
    attributes = function(eci) {
      results = pci:get_eci_attributes(eci).defaultsTo("error",standardError("undefined")); // list of ECIs assigned to userid
      {
        'status'   : (results neq "error"),
        'Attributes' : results
      };
    }
    policy = function(eci) {
      results = pci:get_eci_policy(eci).defaultsTo("error",standardError("undefined")); // list of ECIs assigned to userid
      {
        'status'   : (results neq "error"),
        'Policy' : results
      };
    }
    type = function(channel_id) { // untested!!!!!!!!!!!!!!!!!!!
      channels = Channels().defaultsTo("error",">> undefined >>");

    getType = function(channel_id,channels) {
        channels = channels{"channels"}.defaultsTo("undefined",standardError("undefined"));
        channel = channels.filter( function(channel){channel{"cid"} eq channel_id } ).defaultsTo( "error",standardError("undefined"));
        chan = channel[0];
        type = chan{"type"};
        temp = (type.typeof() eq "str" ) => type | type.typeof() eq "array" => type[0] |  type.keys();
        type2 = (temp.typeof() eq "array") => temp[0] | temp;   
        type2;
      };
      type = ((channels neq "error") && (channels neq {} )) => getType() | "error";
      {
        'status'   : (type neq "error"),
        'channels' : channels
      };
    }
    updateAttrs = defaction(channel_id, attributes){
      set_eci = pci:set_eci_attributes(channel_id, attributes);
      send_directive("updated #{channel_id} attributes");
    }
    updatePolicy = defaction(channel_id, policy){
      set_polcy = pci:set_eci_policy(channel_id, policy); // policy needs to be a map, do we need to cast types?
      send_directive("updated #{channel_id} policy");
    }
    deleteEci = defaction(channelID) {
      deleteeci =pci:delete_eci(channelID);
      send_directive("deleted #{channelID}");
    }
    createEci = defaction(user, options){
      new_eci = pci:new_eci(user, options);
      send_directive("created new eci");
    }
  //-------------------- Apps --------------------
    apps = function() { 
      eci = meta:eci();
      apps = pci:list_apps(eci).defaultsTo("error",standardError("undefined"));
      {
        'status' : (apps neq "error"),
        'apps' : apps
      }
    }    
    get_app = function(appECI){
      apps = apps().defaultsTo("error",standardError("apps"));
      app = apps{appECI}.defaultsTo("error",standardError("app"));
     // app = (apps{appECI}).delete(["appSecret"]).defaultsTo("error",standardError("app"))
      {
        'status' : (app neq "error"),
        'app' : app
      }
    }
    list_bootstrap = function(appECI){
      pci:list_bootstrap(appECI);
    }
    get_appinfo = function(appECI){
      pci:get_appinfo(appECI);
    }
    list_callback = function(appECI){
      pci:list_callback(appECI);
    }
    addPCIbootstraps = defaction(appECI,bootstrapRids){
      boot = bootstrapRids.map(function(rid) { pci:add_bootstrap(appECI, rid); }).klog(">>>>>> bootstrap add result >>>>>>>");
      send_directive("pci bootstraps updated.")
        with rulesets = list_bootstrap(appECI); // is this working?
    }
    removePCIbootstraps = defaction(appEC,IbootstrapRids){
      boot = bootstrapRids.map(function(rid) { pci:remove_bootstrap(appECI, rid); }).klog(">>>>>> bootstrap removed result >>>>>>>");
      send_directive("pci bootstraps removed.")
        with rulesets = list_bootstrap(appECI); 
    }
    removePCIcallback = defaction(appECI,PCIcallbacks){
      PCIcallbacks =( PCIcallbacks || []).append(PCIcallbacks);
      boot = PCIcallbacks.map(function(url) { pci:remove_callback(appECI, url); }).klog(">>>>>> callback remove result >>>>>>>");
      send_directive("pci callback removed.")
        with rulesets = pci:list_callback(appECI);
    }
    update_app = defaction(app_eci,app_data,bootstrap_rids){
      //remove all 
      remove_defact = removePCIcallback(app_eci);
      remove_appinfo = pci:remove_appinfo(app_eci);
      remove_defact = removePCIbootstraps(app_eci);
      // add new 
      add_callback = pci:add_callback(app_eci, app_data{"appCallbackURL"}); 
      add_info = pci:add_appinfo(app_eci,{
        "icon": app_data{"appImageURL"},
        "name": app_data{"appName"},
        "description": app_data{"appDescription"},
        "info_url": app_data{"info_page"},
        "declined_url": app_data{"appDeclinedURL"}
      });
      addPCIbootstraps(app_eci,bootstrap_rids);
    };

		  
	//-------------------- Picos --------------------
  accountProfile = function() {
    profile = pci:get_profile(currentSession()).defaultsTo("error",standardError("undefined"))
    .put( ["oauth_eci"], meta:eci() );
    {
     'status' : (profile neq "error"),
     'profile'  : profile
    }
  }
  currentSession = function() {
    pci:session_token(meta:eci()).defaultsTo("", standardError("pci session_token failed")); // this is old way.. why not just eci??
  };

	children = function() {
		eci = meta:eci();
		children = pci:list_children(eci).defaultsTo("error", standardError("pci children list failed"));
		{
			'status' : (children neq "error"),
			'children' : eci
		}
	}
	parent = function() {
		eci = meta:eci();
		parent = pci:list_parent(eci).defaultsTo("error", standardError("pci parent retrival failed"));
{'fraction_non_alphanumeric': 0.16024637227267982, 'fraction_numerical': 0.0027142708007098864, 'mean_word_length': 2.9454283360790776, 'pattern_counts': {'":': 10, '<': 7, '<?xml version=': 0, '>': 101, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4300914', 'n_tokens_mistral': 5853, 'n_tokens_neox': 5760, 'n_words': 1290}