<commit_before>var vumigo = require("vumigo_v01");
var jed = require("jed");

if (typeof api === "undefined") {
    // testing hook (supplies api when it is not passed in by the real sandbox)
    var api = this.api = new vumigo.dummy_api.DummyApi();
}

var Promise = vumigo.promise.Promise;
var success = vumigo.promise.success;
var Choice = vumigo.states.Choice;
var ChoiceState = vumigo.states.ChoiceState;
var PaginatedChoiceState = vumigo.states.PaginatedChoiceState;
var FreeText = vumigo.states.FreeText;
var EndState = vumigo.states.EndState;
var InteractionMachine = vumigo.state_machine.InteractionMachine;
var StateCreator = vumigo.state_machine.StateCreator;
var JsonApi = vumigo.http_api.JsonApi;

Date.prototype.yyyymmdd = function() {
    var yyyy = this.getFullYear().toString();
    var mm = (this.getMonth()+1).toString(); // getMonth() is zero-based
    var dd  = this.getDate().toString();
    return yyyy + '-' + (mm[1]?mm:"0"+mm[0]) + '-' + (dd[1]?dd:"0"+dd[0]);
};

function GoRtsZambiaError(msg) {
    var self = this;
    self.msg = msg;

    self.toString = function() {
        return "<GoRtsZambiaError: " + self.msg + ">";
    };
}

function GoRtsZambia() {
    var self = this;

    self.headers = {
        'Content-Type': ['application/json']
    };

    // The first state to enter
    StateCreator.call(self, 'initial_state');

    // START Shared helpers

    self.log_result = function() {
        return function (result) {
            var p = im.log('Got result ' + JSON.stringify(result));
            p.add_callback(function() { return result; });
            return p;
        };
    };

    self.cms_get = function(path) {
        var json_api = new JsonApi(im);
        var url = im.config.cms_api_root + path;
        return json_api.get(url);
    };

    self.cms_post = function(path, data) {
        var json_api = new JsonApi(im);
        var url = im.config.cms_api_root + path;
        return json_api.post(url, {data: data, headers: self.headers});
    };

    self.cms_put = function(path, data) {
        var json_api = new JsonApi(im);
        var url = im.config.cms_api_root + path;
        return json_api.put(url, {data: data, headers: self.headers});
    };

    self.url_encode = function(params) {
        var items = [];
        for (var key in params) {
            items[items.length] = (encodeURIComponent(key) + '=' +
                                   encodeURIComponent(params[key]));
        }
        return items.join('&');
    };

    self.check_reply = function(reply, url, method, data, ignore_error) {
        var error;
        if (reply.success && (reply.code >= 200 && reply.code < 300))  {
            if (reply.body) {
                var json = JSON.parse(reply.body);
                return json;
            } else {
                return null;
            }
        }
        else {
            error = reply.reason;
        }
        var error_msg = ("API " + method + " to " + url + " failed: " +
                         error);
        if (typeof data != 'undefined') {
            error_msg = error_msg + '; data: ' + JSON.stringify(data);
        }

        im.log(error_msg);
        if (!ignore_error) {
            throw new GoRtsZambiaError(error_msg);
        }
    };

    self.array_parse_ints = function(target){
        // returns false if fails to parse
        for (var i = 0; i < target.length; i++) {
            target[i] = parseInt(target[i],10);
            if (isNaN(target[i])) return false;
        }
        return target;
    };

    self.check_and_parse_date = function(date_string){
        // an opinionated data parser - expects "DDMMYYYY"
        // returns false if fails to parse
        if (date_string.length != 8) return false;
        var da = [date_string.slice(0,2)];
        da.push(date_string.slice(2,4));
        da.push(date_string.slice(4));
        da = self.array_parse_ints(da);
        if (da && da[0]<=31 && da[1] <= 12){
            da[1] = da[1]-1; // JS dates are 0-bound
            return new Date(da[2], da[1], da[0]);
        } else {
            return false;
        }
    };

    self.check_valid_emis = function(emis){
        // returns false if fails to find
        var numbers_only = new RegExp('^\\d+$');
        if (numbers_only.test(emis)){
            return im.config.array_emis.indexOf(parseInt(emis)) != -1;
        } else {
            return false;
        }
    };

    self.check_valid_number = function(input){
        // an attempt to solve the insanity or JavaScript numbers
        var numbers_only = new RegExp('^\\d+$');
        if (input !== '' && numbers_only.test(input) && !Number.isNaN(Number(input))){
            return true;
        } else {
            return false;
        }
    };

    self.registration_data_school_collect = function(){
        var school_data = {
            "name": im.get_user_answer('reg_school_name'),
            "classrooms": parseInt(im.get_user_answer('reg_school_classrooms')),
            "teachers": parseInt(im.get_user_answer('reg_school_teachers')),
            "teachers_g1": parseInt(im.get_user_answer('reg_school_teachers_g1')),
            "teachers_g2": parseInt(im.get_user_answer('reg_school_teachers_g2')),
            "boys_g2": parseInt(im.get_user_answer('reg_school_students_g2_boys')),
            "girls_g2": parseInt(im.get_user_answer('reg_school_students_g2_girls')),
            "boys": parseInt(im.get_user_answer('reg_school_boys')),
            "girls": parseInt(im.get_user_answer('reg_school_girls'))
        };

        return school_data;
    };

    self.registration_data_headteacher_collect = function(){
        var headteacher_data = {
            "first_name": im.get_user_answer('reg_first_name'),
            "last_name": im.get_user_answer('reg_surname'),
            "msisdn": im.user_addr,
            "date_of_birth": self.check_and_parse_date(im.get_user_answer('reg_date_of_birth')).yyyymmdd(),
            "gender": im.get_user_answer('reg_gender'),
            "emis": "/api/v1/school/emis/" + parseInt(im.get_user_answer('reg_emis_validator')) + "/"
        };
        if (im.get_user_answer('reg_zonal_head') == "reg_zonal_head_name") {
            headteacher_data['zonal_head_name'] = im.get_user_answer('reg_zonal_head_name');
            headteacher_data['is_zonal_head'] = false;
        } else {
            headteacher_data['zonal_head_name'] = "self";
            headteacher_data['is_zonal_head'] = true;
        }
        return headteacher_data;
    };

    self.registration_official_admin_collect = function(){
        var district_admin_data = {
            "first_name": im.get_user_answer("reg_district_official_first_name"),
            "last_name": im.get_user_answer("reg_district_official_surname"),
            "date_of_birth": self.check_and_parse_date(im.get_user_answer('reg_district_official_dob')).yyyymmdd(),
            "district": "/api/v1/district/" + im.get_user_answer("reg_district_official") +"/",
            "id_number": im.get_user_answer("reg_district_official_id_number")
        };
        return district_admin_data;
    };


    self.performance_data_teacher_collect = function(emis, id){
        var data = {
            "ts_number": im.get_user_answer('perf_teacher_ts_number'),
            "gender": im.get_user_answer('perf_teacher_gender'),
            "age": im.get_user_answer('perf_teacher_age'),
            "years_experience": im.get_user_answer('perf_teacher_years_experience'),
            "g2_pupils_present": im.get_user_answer('perf_teacher_g2_pupils_present'),
            "g2_pupils_registered": im.get_user_answer('perf_teacher_g2_pupils_registered'),
            "classroom_environment_score": im.get_user_answer('perf_teacher_classroom_environment_score'),
            "t_l_materials": im.get_user_answer('perf_teacher_t_l_materials'),
            "pupils_materials_score": im.get_user_answer('perf_teacher_pupils_materials_score'),
            "pupils_books_number": im.get_user_answer('perf_teacher_pupils_books_number'),
            "reading_lesson": im.get_user_answer('perf_teacher_reading_lesson'),
            "pupil_engagement_score": im.get_user_answer('perf_teacher_pupil_engagement_score'),
            "attitudes_and_beliefs": im.get_user_answer('perf_teacher_attitudes_and_beliefs'),
            "training_subtotal": im.get_user_answer('perf_teacher_training_subtotal'),
            "academic_level": "/api/v1/data/achievement/" + im.get_user_answer('perf_teacher_academic_level') + "/",
            "reading_assessment": im.get_user_answer('perf_teacher_reading_assessment'),
            "reading_total": im.get_user_answer('perf_teacher_reading_total'),
            "emis": "/api/v1/school/emis/" + emis + "/",
            "created_by": "/api/v1/data/headteacher/" + id + "/"
        };

        return data;
    };

    self.performance_data_learner_collect = function(emis, id){
        var data_boys = {
            "gender": "boys",
            "total_number_pupils": im.get_user_answer('perf_learner_boys_total'),
            "phonetic_awareness": im.get_user_answer('perf_learner_boys_phonetic_awareness'),
            "vocabulary": im.get_user_answer('perf_learner_boys_vocabulary'),
            "reading_comprehension": im.get_user_answer('perf_learner_boys_reading_comprehension'),
            "writing_diction": im.get_user_answer('perf_learner_boys_writing_diction'),
            "outstanding_results": im.get_user_answer('perf_learner_boys_outstanding_results'),
            "desirable_results": im.get_user_answer('perf_learner_boys_desirable_results'),
            "minimum_results": im.get_user_answer('perf_learner_boys_minimum_results'),
            "below_minimum_results": im.get_user_answer('perf_learner_boys_below_minimum_results'),
            "emis": "/api/v1/school/emis/" + emis + "/",
            "created_by": "/api/v1/data/headteacher/" + id + "/"
        };

        var data_girls = {
            "gender": "girls",
            "total_number_pupils": im.get_user_answer('perf_learner_girls_total'),
            "phonetic_awareness": im.get_user_answer('perf_learner_girls_phonetic_awareness'),
            "vocabulary": im.get_user_answer('perf_learner_girls_vocabulary'),
            "reading_comprehension": im.get_user_answer('perf_learner_girls_reading_comprehension'),
            "writing_diction": im.get_user_answer('perf_learner_girls_writing_diction'),
            "outstanding_results": im.get_user_answer('perf_learner_girls_outstanding_results'),
            "desirable_results": im.get_user_answer('perf_learner_girls_desirable_results'),
            "minimum_results": im.get_user_answer('perf_learner_girls_minimum_results'),
            "below_minimum_results": im.get_user_answer('perf_learner_girls_below_minimum_results'),
            "emis": "/api/v1/school/emis/" + emis + "/",
            "created_by": "/api/v1/data/headteacher/" + id + "/"
        };

        return [data_boys, data_girls];
    };

    self.get_contact = function(im){
        var p = im.api_request('contacts.get_or_create', {
            delivery_class: 'ussd',
            addr: im.user_addr
        });
        return p;
    };

    self.clear_contact_extra = function(extra){
        var fields = {};
        fields[extra] = "";
        var p = self.get_contact(im);
        p.add_callback(function(result) {
            return im.api_request('contacts.update_extras', {
                key: result.contact.key,
                fields: fields
            });
        });
        return p;
    };

    // END Shared helpers

    // START CMS Interactions

    self.cms_registration = function(im) {
        var headteacher_data;
        var headteacher_id;

        // get the contact
        var p_c = self.get_contact(im);
        p_c.add_callback(function(result) {
            var contact = result.contact;
            var p_ht;
            if (im.get_user_answer('initial_state') == 'manage_change_emis') {
                // Update current headteacher EMIS only
                headteacher_id = contact['extras-rts_id'];
                headteacher_data = {
                    emis: "/api/v1/school/emis/" + parseInt(im.get_user_answer('manage_change_emis_validator')) + "/"
                };
                p_ht = self.cms_put("data/headteacher/" + headteacher_id + "/", headteacher_data);

            } else if (im.get_user_answer('initial_state') == 'manage_update_school_data') {
                var p = self.get_contact(im);
                p_ht = self.cms_get("data/headteacher/?emis__emis=" + contact["extras-rts_emis"]);
            } else {
                // create new headteacher
                headteacher_data = self.registration_data_headteacher_collect();
                p_ht = self.cms_post("data/headteacher/", headteacher_data);
            }
            // Use the results
            p_ht.add_callback(function(result){
                headteacher_id = result.id;
                var emis = result.emis.emis;
                var school_data = self.registration_data_school_collect();
                school_data["created_by"] = "/api/v1/data/headteacher/" + headteacher_id + "/";
                school_data["emis"] = "/api/v1/school/emis/" + emis + "/";
                var p_school = self.cms_post("data/school/", school_data);
                p_school.add_callback(function(){
                    var fields = {
                        "rts_id": JSON.stringify(headteacher_id),
                        "rts_emis": JSON.stringify(emis)
                    };
                    var p_extra = im.api_request('contacts.update_extras', {
                        key: contact.key,
                        fields: fields
                    });
                    p_extra.add_callback(function(result) {
                        if (result.success === true){
                            var contact = result.contact;
                            contact['name'] = im.get_user_answer('reg_first_name');
                            contact['surname'] = im.get_user_answer('reg_surname');
                            return im.api_request('contacts.update', {
                                key: result.contact.key,
                                fields: contact
                            });
                        } else {
                            var p_log = im.log(result);
                            return p_log;
                        }
                    });
                    return p_extra;
                });
                return p_school;
            });
            return p_ht;
        });
        return p_c;
    };

    self.cms_district_admin_registration = function(im){
        var district_official_data;
        var p_c;
        var p_official_admin;  // Posts districts admin data

        p_c = self.get_contact(im);
        p_c.add_callback(function(result){
            var contact = result.contact;
            district_official_data = self.registration_official_admin_collect();
            var p_district_official = self.cms_post("district_admin/", district_official_data);
            p_district_official.add_callback(function(result){
                var district_official_id = result.id;
                var district_official_id_number = result.id_number;
                var district_official_district_id = result.district.id;

                var fields = {
                    "rts_id": JSON.stringify(district_official_id),
                    "rts_district_official_id_number": JSON.stringify(district_official_id_number),
                    "rts_district_official_district_id": JSON.stringify(district_official_official_district_id)
                };

                var p_extra = im.api_request('contacts.update_extras', {
                        key: contact.key,
                        fields: fields
                    });

                p_extra.add_callback(function(result){
                    if (result.success === true){
                        var contact = result.contact;
                        contact['name'] = im.get_user_answer("reg_district_official_first_name");
                        contact['surname'] = ("reg_district_official_surname");
                        return im.api_request('contacts.update', {
                            key: result.contact.key,
                            fields: contact
                        });

                    } else {
                        var p_log = im.log(result);
                        return p_log;
                    }
                    return p_extra;
                });
            });
            return p_district_official;
        });
        return p_c;
    };

    self.cms_registration_update_msisdn = function(im) {<commit_msg>Fix callback creation and returning<commit_after>var vumigo = require("vumigo_v01");
var jed = require("jed");

if (typeof api === "undefined") {
    // testing hook (supplies api when it is not passed in by the real sandbox)
    var api = this.api = new vumigo.dummy_api.DummyApi();
}

var Promise = vumigo.promise.Promise;
var success = vumigo.promise.success;
var Choice = vumigo.states.Choice;
var ChoiceState = vumigo.states.ChoiceState;
var PaginatedChoiceState = vumigo.states.PaginatedChoiceState;
var FreeText = vumigo.states.FreeText;
var EndState = vumigo.states.EndState;
var InteractionMachine = vumigo.state_machine.InteractionMachine;
var StateCreator = vumigo.state_machine.StateCreator;
var JsonApi = vumigo.http_api.JsonApi;

Date.prototype.yyyymmdd = function() {
    var yyyy = this.getFullYear().toString();
    var mm = (this.getMonth()+1).toString(); // getMonth() is zero-based
    var dd  = this.getDate().toString();
    return yyyy + '-' + (mm[1]?mm:"0"+mm[0]) + '-' + (dd[1]?dd:"0"+dd[0]);
};

function GoRtsZambiaError(msg) {
    var self = this;
    self.msg = msg;

    self.toString = function() {
        return "<GoRtsZambiaError: " + self.msg + ">";
    };
}

function GoRtsZambia() {
    var self = this;

    self.headers = {
        'Content-Type': ['application/json']
    };

    // The first state to enter
    StateCreator.call(self, 'initial_state');

    // START Shared helpers

    self.log_result = function() {
        return function (result) {
            var p = im.log('Got result ' + JSON.stringify(result));
            p.add_callback(function() { return result; });
            return p;
        };
    };

    self.cms_get = function(path) {
        var json_api = new JsonApi(im);
        var url = im.config.cms_api_root + path;
        return json_api.get(url);
    };

    self.cms_post = function(path, data) {
        var json_api = new JsonApi(im);
        var url = im.config.cms_api_root + path;
        return json_api.post(url, {data: data, headers: self.headers});
    };

    self.cms_put = function(path, data) {
        var json_api = new JsonApi(im);
        var url = im.config.cms_api_root + path;
        return json_api.put(url, {data: data, headers: self.headers});
    };

    self.url_encode = function(params) {
        var items = [];
        for (var key in params) {
            items[items.length] = (encodeURIComponent(key) + '=' +
                                   encodeURIComponent(params[key]));
        }
        return items.join('&');
    };

    self.check_reply = function(reply, url, method, data, ignore_error) {
        var error;
        if (reply.success && (reply.code >= 200 && reply.code < 300))  {
            if (reply.body) {
                var json = JSON.parse(reply.body);
                return json;
            } else {
                return null;
            }
        }
        else {
            error = reply.reason;
        }
        var error_msg = ("API " + method + " to " + url + " failed: " +
                         error);
        if (typeof data != 'undefined') {
            error_msg = error_msg + '; data: ' + JSON.stringify(data);
        }

        im.log(error_msg);
        if (!ignore_error) {
            throw new GoRtsZambiaError(error_msg);
        }
    };

    self.array_parse_ints = function(target){
        // returns false if fails to parse
        for (var i = 0; i < target.length; i++) {
            target[i] = parseInt(target[i],10);
            if (isNaN(target[i])) return false;
        }
        return target;
    };

    self.check_and_parse_date = function(date_string){
        // an opinionated data parser - expects "DDMMYYYY"
        // returns false if fails to parse
        if (date_string.length != 8) return false;
        var da = [date_string.slice(0,2)];
        da.push(date_string.slice(2,4));
        da.push(date_string.slice(4));
        da = self.array_parse_ints(da);
        if (da && da[0]<=31 && da[1] <= 12){
            da[1] = da[1]-1; // JS dates are 0-bound
            return new Date(da[2], da[1], da[0]);
        } else {
            return false;
        }
    };

    self.check_valid_emis = function(emis){
        // returns false if fails to find
        var numbers_only = new RegExp('^\\d+$');
        if (numbers_only.test(emis)){
            return im.config.array_emis.indexOf(parseInt(emis)) != -1;
        } else {
            return false;
        }
    };

    self.check_valid_number = function(input){
        // an attempt to solve the insanity or JavaScript numbers
        var numbers_only = new RegExp('^\\d+$');
        if (input !== '' && numbers_only.test(input) && !Number.isNaN(Number(input))){
            return true;
        } else {
            return false;
        }
    };

    self.registration_data_school_collect = function(){
        var school_data = {
            "name": im.get_user_answer('reg_school_name'),
            "classrooms": parseInt(im.get_user_answer('reg_school_classrooms')),
            "teachers": parseInt(im.get_user_answer('reg_school_teachers')),
            "teachers_g1": parseInt(im.get_user_answer('reg_school_teachers_g1')),
            "teachers_g2": parseInt(im.get_user_answer('reg_school_teachers_g2')),
            "boys_g2": parseInt(im.get_user_answer('reg_school_students_g2_boys')),
            "girls_g2": parseInt(im.get_user_answer('reg_school_students_g2_girls')),
            "boys": parseInt(im.get_user_answer('reg_school_boys')),
            "girls": parseInt(im.get_user_answer('reg_school_girls'))
        };

        return school_data;
    };

    self.registration_data_headteacher_collect = function(){
        var headteacher_data = {
            "first_name": im.get_user_answer('reg_first_name'),
            "last_name": im.get_user_answer('reg_surname'),
            "msisdn": im.user_addr,
            "date_of_birth": self.check_and_parse_date(im.get_user_answer('reg_date_of_birth')).yyyymmdd(),
            "gender": im.get_user_answer('reg_gender'),
            "emis": "/api/v1/school/emis/" + parseInt(im.get_user_answer('reg_emis_validator')) + "/"
        };
        if (im.get_user_answer('reg_zonal_head') == "reg_zonal_head_name") {
            headteacher_data['zonal_head_name'] = im.get_user_answer('reg_zonal_head_name');
            headteacher_data['is_zonal_head'] = false;
        } else {
            headteacher_data['zonal_head_name'] = "self";
            headteacher_data['is_zonal_head'] = true;
        }
        return headteacher_data;
    };

    self.registration_official_admin_collect = function(){
        var district_admin_data = {
            "first_name": im.get_user_answer("reg_district_official_first_name"),
            "last_name": im.get_user_answer("reg_district_official_surname"),
            "date_of_birth": self.check_and_parse_date(im.get_user_answer('reg_district_official_dob')).yyyymmdd(),
            "district": "/api/v1/district/" + im.get_user_answer("reg_district_official") +"/",
            "id_number": im.get_user_answer("reg_district_official_id_number")
        };
        return district_admin_data;
    };


    self.performance_data_teacher_collect = function(emis, id){
        var data = {
            "ts_number": im.get_user_answer('perf_teacher_ts_number'),
            "gender": im.get_user_answer('perf_teacher_gender'),
            "age": im.get_user_answer('perf_teacher_age'),
            "years_experience": im.get_user_answer('perf_teacher_years_experience'),
            "g2_pupils_present": im.get_user_answer('perf_teacher_g2_pupils_present'),
            "g2_pupils_registered": im.get_user_answer('perf_teacher_g2_pupils_registered'),
            "classroom_environment_score": im.get_user_answer('perf_teacher_classroom_environment_score'),
            "t_l_materials": im.get_user_answer('perf_teacher_t_l_materials'),
            "pupils_materials_score": im.get_user_answer('perf_teacher_pupils_materials_score'),
            "pupils_books_number": im.get_user_answer('perf_teacher_pupils_books_number'),
            "reading_lesson": im.get_user_answer('perf_teacher_reading_lesson'),
            "pupil_engagement_score": im.get_user_answer('perf_teacher_pupil_engagement_score'),
            "attitudes_and_beliefs": im.get_user_answer('perf_teacher_attitudes_and_beliefs'),
            "training_subtotal": im.get_user_answer('perf_teacher_training_subtotal'),
            "academic_level": "/api/v1/data/achievement/" + im.get_user_answer('perf_teacher_academic_level') + "/",
            "reading_assessment": im.get_user_answer('perf_teacher_reading_assessment'),
            "reading_total": im.get_user_answer('perf_teacher_reading_total'),
            "emis": "/api/v1/school/emis/" + emis + "/",
            "created_by": "/api/v1/data/headteacher/" + id + "/"
        };

        return data;
    };

    self.performance_data_learner_collect = function(emis, id){
        var data_boys = {
            "gender": "boys",
            "total_number_pupils": im.get_user_answer('perf_learner_boys_total'),
            "phonetic_awareness": im.get_user_answer('perf_learner_boys_phonetic_awareness'),
            "vocabulary": im.get_user_answer('perf_learner_boys_vocabulary'),
            "reading_comprehension": im.get_user_answer('perf_learner_boys_reading_comprehension'),
            "writing_diction": im.get_user_answer('perf_learner_boys_writing_diction'),
            "outstanding_results": im.get_user_answer('perf_learner_boys_outstanding_results'),
            "desirable_results": im.get_user_answer('perf_learner_boys_desirable_results'),
            "minimum_results": im.get_user_answer('perf_learner_boys_minimum_results'),
            "below_minimum_results": im.get_user_answer('perf_learner_boys_below_minimum_results'),
            "emis": "/api/v1/school/emis/" + emis + "/",
            "created_by": "/api/v1/data/headteacher/" + id + "/"
        };

        var data_girls = {
            "gender": "girls",
            "total_number_pupils": im.get_user_answer('perf_learner_girls_total'),
            "phonetic_awareness": im.get_user_answer('perf_learner_girls_phonetic_awareness'),
            "vocabulary": im.get_user_answer('perf_learner_girls_vocabulary'),
            "reading_comprehension": im.get_user_answer('perf_learner_girls_reading_comprehension'),
            "writing_diction": im.get_user_answer('perf_learner_girls_writing_diction'),
            "outstanding_results": im.get_user_answer('perf_learner_girls_outstanding_results'),
            "desirable_results": im.get_user_answer('perf_learner_girls_desirable_results'),
            "minimum_results": im.get_user_answer('perf_learner_girls_minimum_results'),
            "below_minimum_results": im.get_user_answer('perf_learner_girls_below_minimum_results'),
            "emis": "/api/v1/school/emis/" + emis + "/",
            "created_by": "/api/v1/data/headteacher/" + id + "/"
        };

        return [data_boys, data_girls];
    };

    self.get_contact = function(im){
        var p = im.api_request('contacts.get_or_create', {
            delivery_class: 'ussd',
            addr: im.user_addr
        });
        return p;
    };

    self.clear_contact_extra = function(extra){
        var fields = {};
        fields[extra] = "";
        var p = self.get_contact(im);
        p.add_callback(function(result) {
            return im.api_request('contacts.update_extras', {
                key: result.contact.key,
                fields: fields
            });
        });
        return p;
    };

    // END Shared helpers

    // START CMS Interactions

    self.cms_registration = function(im) {
        var headteacher_data;
        var headteacher_id;

        // get the contact
        var p_c = self.get_contact(im);
        p_c.add_callback(function(result) {
            var contact = result.contact;
            var p_ht;
            if (im.get_user_answer('initial_state') == 'manage_change_emis') {
                // Update current headteacher EMIS only
                headteacher_id = contact['extras-rts_id'];
                headteacher_data = {
                    emis: "/api/v1/school/emis/" + parseInt(im.get_user_answer('manage_change_emis_validator')) + "/"
                };
                p_ht = self.cms_put("data/headteacher/" + headteacher_id + "/", headteacher_data);

            } else if (im.get_user_answer('initial_state') == 'manage_update_school_data') {
                var p = self.get_contact(im);
                p_ht = self.cms_get("data/headteacher/?emis__emis=" + contact["extras-rts_emis"]);
            } else {
                // create new headteacher
                headteacher_data = self.registration_data_headteacher_collect();
                p_ht = self.cms_post("data/headteacher/", headteacher_data);
            }
            // Use the results
            p_ht.add_callback(function(result){
                headteacher_id = result.id;
                var emis = result.emis.emis;
                var school_data = self.registration_data_school_collect();
                school_data["created_by"] = "/api/v1/data/headteacher/" + headteacher_id + "/";
                school_data["emis"] = "/api/v1/school/emis/" + emis + "/";
                var p_school = self.cms_post("data/school/", school_data);
                p_school.add_callback(function(){
                    var fields = {
                        "rts_id": JSON.stringify(headteacher_id),
                        "rts_emis": JSON.stringify(emis)
                    };
                    var p_extra = im.api_request('contacts.update_extras', {
                        key: contact.key,
                        fields: fields
                    });
                    p_extra.add_callback(function(result) {
                        if (result.success === true){
                            var contact = result.contact;
                            contact['name'] = im.get_user_answer('reg_first_name');
                            contact['surname'] = im.get_user_answer('reg_surname');
                            return im.api_request('contacts.update', {
                                key: result.contact.key,
                                fields: contact
                            });
                        } else {
                            var p_log = im.log(result);
                            return p_log;
                        }
                    });
                    return p_extra;
                });
                return p_school;
            });
            return p_ht;
        });
        return p_c;
    };

    self.cms_district_admin_registration = function(im){
        var p_c = self.get_contact(im);
        p_c.add_callback(function(result){
            var contact = result.contact;
            var district_official_data = self.registration_official_admin_collect();
            var p_district_official = self.cms_post("district_admin/", district_official_data);
            p_district_official.add_callback(function(result){
                var district_official_id = result.id;
                var district_official_id_number = result.id_number;
                var district_official_district_id = result.district.id;

                var fields = {
                    "rts_id": JSON.stringify(district_official_id),
                    "rts_district_official_id_number": JSON.stringify(district_official_id_number),
                    "rts_district_official_district_id": JSON.stringify(district_official_official_district_id)
                };

                var p_extra = im.api_request('contacts.update_extras', {
                    key: contact.key,
                    fields: fields
                });

                p_extra.add_callback(function(result){
                    if (result.success === true){
                        var contact = result.contact;
                        contact['name'] = im.get_user_answer("reg_district_official_first_name");
                        contact['surname'] = ("reg_district_official_surname");
                        return im.api_request('contacts.update', {
                            key: result.contact.key,
                            fields: contact
                        });

                    } else {
                        var p_log = im.log(result);
                        return p_log;
                    }
                });
                return p_extra;
            });
            return p_district_official;
        });
        return p_c;
    };

    self.cms_registration_update_msisdn = function(im) {
{'fraction_non_alphanumeric': 0.1194471865745311, 'fraction_numerical': 0.0037093541535792277, 'mean_word_length': 2.132496251874063, 'pattern_counts': {'":': 136, '<': 13, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2207134', 'n_tokens_mistral': 10482, 'n_tokens_neox': 9947, 'n_words': 1518}