#include "RenamePrimCommand.h"
#include "../../utils/Logger.h"
#include <pxr/usd/usd/namespaceEditor.h>
#include <pxr/usd/usd/prim.h>
#include <pxr/base/tf/token.h>

PXR_NAMESPACE_USING_DIRECTIVE

namespace UsdLayerManager {

RenamePrimCommand::RenamePrimCommand(UsdStageRefPtr     stage,
                                     const SdfPath&     primPath,
                                     const std::string& newName)
    : m_stage(stage)
    , m_oldPath(primPath)
    , m_oldName(primPath.GetName())
    , m_newName(newName)
    , m_description("Rename " + primPath.GetName() + " \xe2\x86\x92 " + newName)
{
    m_newPath = primPath.GetParentPath().AppendChild(TfToken(newName));
}

void RenamePrimCommand::Execute() {
    UsdPrim prim = m_stage->GetPrimAtPath(m_oldPath);
    if (!prim.IsValid()) {
        LOG_ERROR("RenamePrimCommand::Execute: prim not found: " + m_oldPath.GetString());
        return;
    }
    UsdNamespaceEditor editor(m_stage);
    if (!editor.RenamePrim(prim, TfToken(m_newName))) {
        LOG_ERROR("RenamePrimCommand::Execute: RenamePrim() rejected for " + m_oldPath.GetString());
        return;
    }
    std::string whyNot;
    if (!editor.CanApplyEdits(&whyNot)) {
        LOG_ERROR("RenamePrimCommand::Execute: cannot rename " + m_oldPath.GetString() + ": " + whyNot);
        return;
    }
    if (!editor.ApplyEdits()) {
        LOG_ERROR("RenamePrimCommand::Execute: ApplyEdits failed for " + m_oldPath.GetString());
    }
}

void RenamePrimCommand::Undo() {
    UsdPrim prim = m_stage->GetPrimAtPath(m_newPath);
    if (!prim.IsValid()) {
        LOG_ERROR("RenamePrimCommand::Undo: prim not found: " + m_newPath.GetString());
        return;
    }
    UsdNamespaceEditor editor(m_stage);
    if (!editor.RenamePrim(prim, TfToken(m_oldName))) {
        LOG_ERROR("RenamePrimCommand::Undo: RenamePrim() rejected for " + m_newPath.GetString());
        return;
    }
    std::string whyNot;
    if (!editor.CanApplyEdits(&whyNot)) {
        LOG_ERROR("RenamePrimCommand::Undo: cannot rename back " + m_newPath.GetString() + ": " + whyNot);
        return;
    }
    if (!editor.ApplyEdits()) {
        LOG_ERROR("RenamePrimCommand::Undo: ApplyEdits failed for " + m_newPath.GetString());
    }
}

} // namespace UsdLayerManager
