/**
 *  Command for changing amount of money players have.
 *      Copyright 2022-2023 Anton Tarasenko
 *------------------------------------------------------------------------------
 * This file is part of Acedia.
 *
 * Acedia is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 3 of the License, or
 * (at your option) any later version.
 *
 * Acedia is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Acedia.  If not, see <https://www.gnu.org/licenses/>.
 */
class ACommandUserData extends Command;

var private array<EPlayer> playerQueue;

protected function BuildData(CommandDataBuilder builder)
{
    builder.Group(P("admin"));
    builder.Summary(P("Allows to read and write custom user data for players."));
    builder.RequireTarget();
    builder.ParamText(P("groupName"));
    builder.OptionalParams();
    builder.ParamText(P("dataName"));
    builder.Describe(F("Reads user data stored for targeted user under group"
            @ "{$TextEmphasis `groupName`} and name"
            @ "{$TextEmphasis `dataName`}. If {$TextEmphasis `dataName`} is"
            @ "omitted, the data inside the whole group will be read."));
    builder.SubCommand(P("write"));
    builder.ParamText(P("groupName"));
    builder.ParamText(P("dataName"));
    builder.ParamJSON(P("newData"));
    builder.Describe(F("Stores new user data {$TextEmphasis `newData`} for"
            @ "targeted user under group {$TextEmphasis `groupName`} and name"
            @ "{$TextEmphasis `dataName`}."));
}

protected function ExecutedFor(
    EPlayer     target,
    CallData    arguments,
    EPlayer     instigator,
    CommandPermissions permissions
) {
    local AcediaObject  userData;
    local Text          groupName, dataName;

    groupName   = arguments.parameters.GetText(P("groupName"));
    dataName    = arguments.parameters.GetText(P("dataName"));
    userData    = arguments.parameters.GetItem(P("newData"));
    if (arguments.subCommandName.IsEmpty()) {
        ReadUserData(target, groupName, dataName);
    }
    else {
        WriteUserData(target, groupName, dataName, userData);
    }
    _.memory.Free(dataName);
    _.memory.Free(groupName);
}

private final function ReadUserData(
    EPlayer     targetPlayer,
    BaseText    groupName,
    BaseText    dataName)
{
    local User          identity;
    local AcediaObject  rawData;
    local MutableText   dataAsJSON;
    local Text          targetPlayerName;

    identity = targetPlayer.GetIdentity();
    if (identity == none) {
        return;
    }
    targetPlayerName = targetPlayer.GetName();
    rawData = identity.GetPersistentData(groupName, dataName);
    dataAsJSON = _.json.PrettyPrint(rawData);
    targetPlayer.BorrowConsole()
        .Write(F("User data for player "))
        .Write(targetPlayerName)
        .Write(P(": "))
        .WriteLine(dataAsJSON);
    _.memory.Free(dataAsJSON);
    _.memory.Free(rawData);
    _.memory.Free(targetPlayerName);
    _.memory.Free(identity);
}

private final function WriteUserData(
    EPlayer         targetPlayer,
    BaseText        groupName,
    BaseText        dataName,
    AcediaObject    rawData)
{
    local User identity;
    local Text targetPlayerName;

    identity = targetPlayer.GetIdentity();
    if (identity == none) {
        return;
    }
    targetPlayerName = targetPlayer.GetName();
    if (identity.SetPersistentData(groupName, dataName, rawData))
    {
        targetPlayer.BorrowConsole()
            .Write(P("User data for player "))
            .Write(targetPlayerName)
            .WriteLine(F(" was {$TextPositive successfully} changed!"));
    }
    else
    {
        targetPlayer.BorrowConsole()
            .Write(P("User data for player "))
            .Write(targetPlayerName)
            .WriteLine(F(" has {$TextPositive failed} to change!"));
    }
    _.memory.Free(targetPlayerName);
    _.memory.Free(identity);
}

defaultproperties {
    preferredName = "userdata"
}