<commit_before>'use strict';

var pg = require('pg');
var LargeObjectManager = require('pg-large-object').LargeObjectManager;
var shortid = require('shortid');
var moment = require('moment');

module.exports = function (options) {
  var seneca = this;

  var PARENT_GUARDIAN_PROFILE_ENTITY = 'cd/profiles';
  var plugin = 'cd-profiles';
  var _ = require('lodash');
  var async = require('async');
  var hiddenFields = require('./data/hidden-fields.js');

  var syncedFields = [
    'name',
    'email',
    'phone'
  ];

  var mentorPublicFields = [
    'name',
    'languagesSpoken',
    'programmingLanguages',
    'linkedin',
    'twitter',
    'userTypes',
    'dojos',
    'badges',
    'optionalHiddenFields'
  ];

  var championPublicFields = [
    'id',
    'name',
    'languagesSpoken',
    'programmingLanguages',
    'linkedin',
    'twitter',
    'userTypes',
    'projects',
    'notes',
    'dojos',
    'optionalHiddenFields'
  ];

  var attendeeO13PublicFields = [
    'alias',
    'linkedin',
    'twitter',
    'badges',
    'userTypes',
    'optionalHiddenFields'
  ];

  var fieldWhiteList = {
    'mentor': mentorPublicFields,
    'champion': championPublicFields,
    'attendee-o13': attendeeO13PublicFields
  };

  // var allowedOptionalFieldsYouth = ['dojos', 'linkedin', 'twitter', 'badges'];
  var allowedOptionalFieldsYouth = _.filter(hiddenFields, function (field) {
    if (_.contains(field.allowedUserTypes, 'attendee-o13')) return field.modelName;
  });

  // var allowedOptionalFieldsChampion = ['notes', 'projects'];
  var allowedOptionalFieldsChampion = _.map(hiddenFields, function (field) {
    if (_.contains(field.allowedUserTypes, 'champion')) return field.modelName;
  });

  var allowedOptionalFieldsMentor = _.map(hiddenFields, function (field) {
    if (_.contains(field.allowedUserTypes, 'mentor')) return field.modelName;
  });

  var allowedOptionalFields = {
    'champion': allowedOptionalFieldsChampion,
    'attendee-o13': allowedOptionalFieldsYouth,
    'mentor': allowedOptionalFieldsMentor
  };

  var immutableFields = ['userType', 'avatar'];

  var youthBlackList = ['name'];

  var requiredProfileFields = ['name', 'alias', 'dob', 'country', 'place', 'address'];

  // var userTypes = ['champion', 'mentor', 'parent-guardian', 'attendee-o13', 'attendee-u13'];
  // var userTypes = ['attendee-u13', 'attendee-o13', 'parent-guardian', 'mentor', 'champion'];

  seneca.add({role: plugin, cmd: 'create'}, cmd_create);
  seneca.add({role: plugin, cmd: 'user_profile_data'}, cmd_user_profile_data);
  seneca.add({role: plugin, cmd: 'load'}, cmd_load);
  seneca.add({role: plugin, cmd: 'save-youth-profile'}, cmd_save_youth_profile);
  seneca.add({role: plugin, cmd: 'save'}, cmd_save);
  seneca.add({role: plugin, cmd: 'update-youth-profile'}, cmd_update_youth);
  seneca.add({role: plugin, cmd: 'invite-parent-guardian'}, cmd_invite_parent_guardian);
  seneca.add({role: plugin, cmd: 'search'}, cmd_search);
  seneca.add({role: plugin, cmd: 'accept_parent_invite'}, cmd_accept_parent_invite);
  seneca.add({role: plugin, cmd: 'load_hidden_fields'}, cmd_load_hidden_fields);
  seneca.add({role: plugin, cmd: 'list'}, cmd_list);
  seneca.add({role: plugin, cmd: 'change_avatar'}, cmd_change_avatar);
  seneca.add({role: plugin, cmd: 'get_avatar'}, cmd_get_avatar);
  seneca.add({role: plugin, cmd: 'load_parents_for_user'}, cmd_load_parents_for_user);
  seneca.add({role: plugin, cmd: 'invite_ninja'}, cmd_invite_ninja);
  seneca.add({role: plugin, cmd: 'approve_invite_ninja'}, cmd_approve_invite_ninja);

  function cmd_search (args, done) {
    if (!args.query) {
      return done(new Error('Empty query'));
    }

    seneca.make$(PARENT_GUARDIAN_PROFILE_ENTITY).list$(args.query, done);
  }

  function cmd_create (args, done) {
    var profile = args.profile;

    async.series([
      validateRequest,
      saveProfile
    ], function (err, res) {
      if (err) return done(null, {ok: false, why: err.message});
      return done(null, res);
    });

    function validateRequest (done) {
      var profileEntity = seneca.make$(PARENT_GUARDIAN_PROFILE_ENTITY);
      profileEntity.load$(profile.id, function (err, originalProfile) {
        if (err) return done(err);
        if (!originalProfile) return done();
        if (originalProfile.email !== profile.email) {
          seneca.act({role: 'cd-users', cmd: 'list', query: {nick: profile.email}}, function (err, users) {
            if (err) return done(err);
            if (!_.isEmpty(users)) return done(new Error('This email is already associated with an account.'));
            return done();
          });
        } else {
          return done();
        }
      });
    }

    function saveProfile (done) {
      var profileKeys = _.keys(profile);
      var missingKeys = _.difference(requiredProfileFields, profileKeys);
      if (_.isEmpty(missingKeys)) profile.requiredFieldsComplete = true;
      if (args.user !== profile.userId) return done(null, new Error('Profiles can only be saved by the profile user.'));
      if (profile.id) {
        profile = _.omit(profile, immutableFields);
      }
      seneca.make$(PARENT_GUARDIAN_PROFILE_ENTITY).save$(profile, function (err, profile) {
        if (err) return done(err);

        syncUserObj(profile, function (err, res) {
          if (err) return done(err);

          syncForumProfile(profile, function (err, res) {
            if (err) seneca.log.error(err);
            var query = {userId: profile.userId};
            seneca.act({role: plugin, cmd: 'load'}, query, done);
          });
        });
      });
    }
  }

  function syncUserObj (profile, done) {
    var updatedFields = {};
    updatedFields.id = profile.userId;
    _.each(syncedFields, function (field) {
      updatedFields[field] = profile[field];
    });
    if (updatedFields.email) updatedFields.nick = profile.email;
    seneca.act({role: 'cd-users', cmd: 'update', user: updatedFields}, done);
  }

  function syncForumProfile (profile, done) {
    var forumProfile = _.clone(profile);
    forumProfile.username = forumProfile.name;
    seneca.act({role: 'cd-nodebb-api', cmd: 'update', user: forumProfile}, done);
  }

  function cmd_save_youth_profile (args, done) {
    var profile = args.profile;
    profile.parents = [];
    profile.parents.push(args.user);

    if (profile.id) {
      profile = _.omit(profile, immutableFields);<commit_msg>adding edit champion profile functionality<commit_after>'use strict';

var pg = require('pg');
var LargeObjectManager = require('pg-large-object').LargeObjectManager;
var shortid = require('shortid');
var moment = require('moment');

module.exports = function (options) {
  var seneca = this;

  var PARENT_GUARDIAN_PROFILE_ENTITY = 'cd/profiles';
  var plugin = 'cd-profiles';
  var _ = require('lodash');
  var async = require('async');
  var hiddenFields = require('./data/hidden-fields.js');

  var syncedFields = [
    'name',
    'email',
    'phone'
  ];

  var mentorPublicFields = [
    'name',
    'languagesSpoken',
    'programmingLanguages',
    'linkedin',
    'twitter',
    'userTypes',
    'dojos',
    'badges',
    'optionalHiddenFields'
  ];

  var championPublicFields = [
    'id',
    'name',
    'languagesSpoken',
    'programmingLanguages',
    'linkedin',
    'twitter',
    'userTypes',
    'projects',
    'notes',
    'dojos',
    'optionalHiddenFields'
  ];

  var attendeeO13PublicFields = [
    'alias',
    'linkedin',
    'twitter',
    'badges',
    'userTypes',
    'optionalHiddenFields'
  ];

  var fieldWhiteList = {
    'mentor': mentorPublicFields,
    'champion': championPublicFields,
    'attendee-o13': attendeeO13PublicFields
  };

  // var allowedOptionalFieldsYouth = ['dojos', 'linkedin', 'twitter', 'badges'];
  var allowedOptionalFieldsYouth = _.filter(hiddenFields, function (field) {
    if (_.contains(field.allowedUserTypes, 'attendee-o13')) return field.modelName;
  });

  // var allowedOptionalFieldsChampion = ['notes', 'projects'];
  var allowedOptionalFieldsChampion = _.map(hiddenFields, function (field) {
    if (_.contains(field.allowedUserTypes, 'champion')) return field.modelName;
  });

  var allowedOptionalFieldsMentor = _.map(hiddenFields, function (field) {
    if (_.contains(field.allowedUserTypes, 'mentor')) return field.modelName;
  });

  var allowedOptionalFields = {
    'champion': allowedOptionalFieldsChampion,
    'attendee-o13': allowedOptionalFieldsYouth,
    'mentor': allowedOptionalFieldsMentor
  };

  var immutableFields = ['userType', 'avatar'];

  var youthBlackList = ['name'];

  var requiredProfileFields = ['name', 'alias', 'dob', 'country', 'place', 'address'];

  // var userTypes = ['champion', 'mentor', 'parent-guardian', 'attendee-o13', 'attendee-u13'];
  // var userTypes = ['attendee-u13', 'attendee-o13', 'parent-guardian', 'mentor', 'champion'];

  seneca.add({role: plugin, cmd: 'create'}, cmd_create);
  seneca.add({role: plugin, cmd: 'user_profile_data'}, cmd_user_profile_data);
  seneca.add({role: plugin, cmd: 'load'}, cmd_load);
  seneca.add({role: plugin, cmd: 'save-youth-profile'}, cmd_save_youth_profile);
  seneca.add({role: plugin, cmd: 'save'}, cmd_save);
  seneca.add({role: plugin, cmd: 'update-youth-profile'}, cmd_update_youth);
  seneca.add({role: plugin, cmd: 'invite-parent-guardian'}, cmd_invite_parent_guardian);
  seneca.add({role: plugin, cmd: 'search'}, cmd_search);
  seneca.add({role: plugin, cmd: 'accept_parent_invite'}, cmd_accept_parent_invite);
  seneca.add({role: plugin, cmd: 'load_hidden_fields'}, cmd_load_hidden_fields);
  seneca.add({role: plugin, cmd: 'list'}, cmd_list);
  seneca.add({role: plugin, cmd: 'change_avatar'}, cmd_change_avatar);
  seneca.add({role: plugin, cmd: 'get_avatar'}, cmd_get_avatar);
  seneca.add({role: plugin, cmd: 'load_parents_for_user'}, cmd_load_parents_for_user);
  seneca.add({role: plugin, cmd: 'invite_ninja'}, cmd_invite_ninja);
  seneca.add({role: plugin, cmd: 'approve_invite_ninja'}, cmd_approve_invite_ninja);

  function cmd_search (args, done) {
    if (!args.query) {
      return done(new Error('Empty query'));
    }

    seneca.make$(PARENT_GUARDIAN_PROFILE_ENTITY).list$(args.query, done);
  }

  function cmd_create (args, done) {
    var profile = args.profile;

    async.series([
      validateRequest,
      saveProfile
    ], function (err, res) {
      if (err) return done(null, {ok: false, why: err.message});
      return done(null, res);
    });

    function validateRequest (done) {
      var profileEntity = seneca.make$(PARENT_GUARDIAN_PROFILE_ENTITY);
      profileEntity.load$(profile.id, function (err, originalProfile) {
        if (err) return done(err);
        if (!originalProfile) return done();
        if (originalProfile.email !== profile.email) {
          seneca.act({role: 'cd-users', cmd: 'list', query: {nick: profile.email}}, function (err, users) {
            if (err) return done(err);
            if (!_.isEmpty(users)) return done(new Error('This email is already associated with an account.'));
            return done();
          });
        } else {
          return done();
        }
      });
    }

    function saveProfile (done) {
      var profileKeys = _.keys(profile);
      var missingKeys = _.difference(requiredProfileFields, profileKeys);
      if (_.isEmpty(missingKeys)) profile.requiredFieldsComplete = true;
      if (args.user !== profile.userId) return done(null, new Error('Profiles can only be saved by the profile user.'));
      if (profile.id) {
        profile = _.omit(profile, immutableFields);
      }
      seneca.make$(PARENT_GUARDIAN_PROFILE_ENTITY).save$(profile, function (err, profile) {
        if (err) return done(err);

        if (process.env.SALESFORCE_ENABLED === 'true') {
          process.nextTick(function() { updateSalesForce(profile) });
        }

        syncUserObj(profile, function (err, res) {
          if (err) return done(err);

          syncForumProfile(profile, function (err, res) {
            if (err) seneca.log.error(err);
            var query = {userId: profile.userId};
            seneca.act({role: plugin, cmd: 'load'}, query, done);
          });
        });
      });
    }
  }

  function salesForceLogger(level, message) {
    if(level === "error") {
      seneca.log.error(message);
    } else if(level === "success") {
      seneca.log.info(message);
    } else if(level === "info") {
      seneca.log.info(message);
    }
  }

  function updateSalesForce (profile) {
    seneca.make$(PARENT_GUARDIAN_PROFILE_ENTITY).load$(profile.id, function (err, res) {
      if(err) return salesForceLogger("error", "[error][salesforce] profile id: " + profile.id + " not present");

      if(res.userType.toLowerCase() === "champion") {
        var dobOffset = moment(profile.dob).utcOffset();
        var account = {
          PlatformId__c: profile.userId,
        };
        _.extend(account, {
          Name: profile.name,
          Email__c: profile.email,
          DateofBirth__c: moment.utc(profile.dob).add(dobOffset, 'minutes'),
          BillingCountry: profile.country.countryName || null,
          BillingCity: profile.place.nameWithHierarchy || null,
          BillingState: profile.place.admin2Name || null,
          BillingStreet: profile.address || null,
          Phone: profile.phone || null,
          Linkedin__c: profile.linkedin || null,
          Twitter__c: (profile.twitter) ? "https://twitter.com/" + profile.twitter : null,
          Notes__c: profile.notes || null,
          Projects__c: profile.projects || null,
          ProgrammingLanguages__c: (profile.programmingLanguages) ?  profile.programmingLanguages.join(';') : null,
          LanguagesSpoken__c: (profile.languagesSpoken) ? profile.languagesSpoken.join(';') : null
        });

        seneca.act('role:cd-salesforce,cmd:save_account', {userId: profile.userId, account: account}, function (err, res) {
          if(err) return salesForceLogger("error", "[error][salesforce] error saving champion account id: " + profile.userId);
          return salesForceLogger("success", "[salesforce] updated champion account id: " + profile.userId);
        });
      }
      return;
    });
  }

  function syncUserObj (profile, done) {
    var updatedFields = {};
    updatedFields.id = profile.userId;
    _.each(syncedFields, function (field) {
      updatedFields[field] = profile[field];
    });
    if (updatedFields.email) updatedFields.nick = profile.email;
    seneca.act({role: 'cd-users', cmd: 'update', user: updatedFields}, done);
  }

  function syncForumProfile (profile, done) {
    var forumProfile = _.clone(profile);
    forumProfile.username = forumProfile.name;
    seneca.act({role: 'cd-nodebb-api', cmd: 'update', user: forumProfile}, done);
  }

  function cmd_save_youth_profile (args, done) {
    var profile = args.profile;
    profile.parents = [];
    profile.parents.push(args.user);

    if (profile.id) {
      profile = _.omit(profile, immutableFields);
{'fraction_non_alphanumeric': 0.14932247513517122, 'fraction_numerical': 0.002469795073760096, 'mean_word_length': 3.5468892261001517, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 1, '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': '558885', 'n_tokens_mistral': 4792, 'n_tokens_neox': 4701, 'n_words': 1009}