Source: classes/users/User.js

/** @module classes */

const BaseFactory = require('../Base.js');
const UserController = require('../../controllers/UserController.js');

/** Class representing a user. */
class User {
    constructor(id, name, accountIdentifier, authToken, authMethod, createdAt) {
        this.id = id;
        this.name = name;
        this.accountIdentifier = accountIdentifier;
        this.authToken = authToken;
        this.authMethod = authMethod;
        this.createdAt = createdAt;
    }

    /** Set a meta value for the user. */
    async setMeta(name, value) {
        await new UserController().setMeta(this.id, name, value);
    }

    /** Get a meta value for the user. */
    async getMeta(name) {
        return await new UserController().getMeta(this.id, name);
    }

    /** Deletes a user. */
    async delete() {
        await new UserController().delete(this.id);
    }

    /** Add a contribution to the user. */
    async addContribution(code, recordId) {
        await new UserController().addContribution(this.id, code, recordId);
    }

    /** Get the contribution points of the user. */
    async getContributionPoints() {
        return await new UserController().getContributionPoints(this.id);
    }

    /** Get the contributions of the user. */
    async getGoals() {
        return await new UserController().getGoals(this.id);
    }

    /** Add goals if they do not exist. */
    async addGoalsIfNotExists() {
        return await new UserController().addGoalsIfNotExists(this.id);
    }

    /** Change the progress of a goal by name. */
    async changeGoalProgressByTrackName(goalName, goalDesc, changeByAmount) {
        return await new UserController().changeGoalProgressByTrackName(this.id, goalName, goalDesc, changeByAmount);
    }

    /** Get the contribution type. */
    async getContributionType(code) {
        return await new UserController().getContributionType(code);
    }

    /** Get the scans of the user. */
    async getScans() {
        return await new UserController().getScans(this.id);
    }
}

/** Class representing a user factory. */
class UserFactory extends BaseFactory {
    /** Set the id of the user. */
    setId(id) {
        this.id = id;
        
        return this;
    }

    /** Set the name of the user. */
    setName(name) {
        this.name = name;
        
        return this;
    }

    /** Set the account identifier of the user. */
    setAccountIdentifier(accountIdentifier) {
        this.accountIdentifier = accountIdentifier;
        
        return this;
    }

    /** Set the auth token of the user. */
    setAuthToken(authToken) {
        this.authToken = authToken;
        
        return this;
    }

    /** Set the auth method of the user. */
    setAuthMethod(authMethod) {
        this.authMethod = authMethod;
        
        return this;
    }

    /** Set the created at of the user. */
    setCreatedAt(createdAt) {
        this.createdAt = createdAt;
        
        return this;
    }

    /** Load a term from a database object. */
    load(dbObject) {
        this.setId(dbObject.id);
        this.setName(dbObject.name);
        this.setAccountIdentifier(dbObject.account_identifier);
        this.setAuthToken(dbObject.auth_token);
        this.setAuthMethod(dbObject.auth_method);
        this.setCreatedAt(dbObject.created_at);

        return this;
    }

    /** 
     * Create the user.
     * 
     * @returns {Promise<User>} The user object.
     */
    async create() {
        if (!this.id) {
            return null;
        } else if (!this.name && !this.accountIdentifier && !this.authToken && !this.authMethod && !this.createdAt) {
            this.load(await new UserController().byId(this.id));
        }
        
        return new User(this.id, this.name, this.accountIdentifier, this.authToken, this.authMethod, this.createdAt);
    }
}

module.exports = { User, UserFactory };