/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "property_name_mapper_impl.h"

#include "define_multimodal.h"
#include "i_input_service_context.h"
#include "key_event.h"

#undef MMI_LOG_DOMAIN
#define MMI_LOG_DOMAIN MMI_LOG_SERVER
#undef MMI_LOG_TAG
#define MMI_LOG_TAG "PropertyNameMapperImpl"

#define DEFINE_KEYCODE(key) { #key, KeyEvent::KEYCODE_##key }
#define DEFINE_AXIS(axis)   { #axis, PointerEvent::AXIS_TYPE_ABS_##axis }

namespace OHOS {
namespace MMI {
namespace {
const std::unordered_map<std::string, int32_t> KEYCODES {
    DEFINE_KEYCODE(UNKNOWN),
    DEFINE_KEYCODE(HOME),
    DEFINE_KEYCODE(BACK),
    DEFINE_KEYCODE(CALL),
    DEFINE_KEYCODE(ENDCALL),
    DEFINE_KEYCODE(0),
    DEFINE_KEYCODE(1),
    DEFINE_KEYCODE(2),
    DEFINE_KEYCODE(3),
    DEFINE_KEYCODE(4),
    DEFINE_KEYCODE(5),
    DEFINE_KEYCODE(6),
    DEFINE_KEYCODE(7),
    DEFINE_KEYCODE(8),
    DEFINE_KEYCODE(9),
    DEFINE_KEYCODE(STAR),
    DEFINE_KEYCODE(POUND),
    DEFINE_KEYCODE(DPAD_UP),
    DEFINE_KEYCODE(DPAD_DOWN),
    DEFINE_KEYCODE(DPAD_LEFT),
    DEFINE_KEYCODE(DPAD_RIGHT),
    DEFINE_KEYCODE(DPAD_CENTER),
    DEFINE_KEYCODE(VOLUME_UP),
    DEFINE_KEYCODE(VOLUME_DOWN),
    DEFINE_KEYCODE(POWER),
    DEFINE_KEYCODE(CAMERA),
    DEFINE_KEYCODE(CLEAR),
    DEFINE_KEYCODE(A),
    DEFINE_KEYCODE(B),
    DEFINE_KEYCODE(C),
    DEFINE_KEYCODE(D),
    DEFINE_KEYCODE(E),
    DEFINE_KEYCODE(F),
    DEFINE_KEYCODE(G),
    DEFINE_KEYCODE(H),
    DEFINE_KEYCODE(I),
    DEFINE_KEYCODE(J),
    DEFINE_KEYCODE(K),
    DEFINE_KEYCODE(L),
    DEFINE_KEYCODE(M),
    DEFINE_KEYCODE(N),
    DEFINE_KEYCODE(O),
    DEFINE_KEYCODE(P),
    DEFINE_KEYCODE(Q),
    DEFINE_KEYCODE(R),
    DEFINE_KEYCODE(S),
    DEFINE_KEYCODE(T),
    DEFINE_KEYCODE(U),
    DEFINE_KEYCODE(V),
    DEFINE_KEYCODE(W),
    DEFINE_KEYCODE(X),
    DEFINE_KEYCODE(Y),
    DEFINE_KEYCODE(Z),
    DEFINE_KEYCODE(COMMA),
    DEFINE_KEYCODE(PERIOD),
    DEFINE_KEYCODE(ALT_LEFT),
    DEFINE_KEYCODE(ALT_RIGHT),
    DEFINE_KEYCODE(SHIFT_LEFT),
    DEFINE_KEYCODE(SHIFT_RIGHT),
    DEFINE_KEYCODE(TAB),
    DEFINE_KEYCODE(SPACE),
    DEFINE_KEYCODE(SYM),
    DEFINE_KEYCODE(EXPLORER),
    DEFINE_KEYCODE(ENVELOPE),
    DEFINE_KEYCODE(ENTER),
    DEFINE_KEYCODE(DEL),
    DEFINE_KEYCODE(GRAVE),
    DEFINE_KEYCODE(MINUS),
    DEFINE_KEYCODE(EQUALS),
    DEFINE_KEYCODE(LEFT_BRACKET),
    DEFINE_KEYCODE(RIGHT_BRACKET),
    DEFINE_KEYCODE(BACKSLASH),
    DEFINE_KEYCODE(SEMICOLON),
    DEFINE_KEYCODE(APOSTROPHE),
    DEFINE_KEYCODE(SLASH),
    DEFINE_KEYCODE(AT),
    DEFINE_KEYCODE(HEADSETHOOK),
    DEFINE_KEYCODE(FOCUS),
    DEFINE_KEYCODE(PLUS),
    DEFINE_KEYCODE(MENU),
    DEFINE_KEYCODE(NOTIFICATION),
    DEFINE_KEYCODE(SEARCH),
    DEFINE_KEYCODE(MEDIA_PLAY_PAUSE),
    DEFINE_KEYCODE(MEDIA_STOP),
    DEFINE_KEYCODE(MEDIA_NEXT),
    DEFINE_KEYCODE(MEDIA_PREVIOUS),
    DEFINE_KEYCODE(MEDIA_REWIND),
    DEFINE_KEYCODE(MEDIA_FAST_FORWARD),
    DEFINE_KEYCODE(MUTE),
    DEFINE_KEYCODE(PAGE_UP),
    DEFINE_KEYCODE(PAGE_DOWN),
    DEFINE_KEYCODE(BUTTON_A),
    DEFINE_KEYCODE(BUTTON_B),
    DEFINE_KEYCODE(BUTTON_C),
    DEFINE_KEYCODE(BUTTON_X),
    DEFINE_KEYCODE(BUTTON_Y),
    DEFINE_KEYCODE(BUTTON_Z),
    DEFINE_KEYCODE(BUTTON_L1),
    DEFINE_KEYCODE(BUTTON_R1),
    DEFINE_KEYCODE(BUTTON_L2),
    DEFINE_KEYCODE(BUTTON_R2),
    DEFINE_KEYCODE(BUTTON_SELECT),
    DEFINE_KEYCODE(BUTTON_START),
    DEFINE_KEYCODE(BUTTON_MODE),
    DEFINE_KEYCODE(BUTTON_THUMBL),
    DEFINE_KEYCODE(BUTTON_THUMBR),
    DEFINE_KEYCODE(ESCAPE),
    DEFINE_KEYCODE(FORWARD_DEL),
    DEFINE_KEYCODE(CTRL_LEFT),
    DEFINE_KEYCODE(CTRL_RIGHT),
    DEFINE_KEYCODE(CAPS_LOCK),
    DEFINE_KEYCODE(SCROLL_LOCK),
    DEFINE_KEYCODE(META_LEFT),
    DEFINE_KEYCODE(META_RIGHT),
    DEFINE_KEYCODE(FUNCTION),
    DEFINE_KEYCODE(SYSRQ),
    DEFINE_KEYCODE(BREAK),
    DEFINE_KEYCODE(MOVE_HOME),
    DEFINE_KEYCODE(MOVE_END),
    DEFINE_KEYCODE(INSERT),
    DEFINE_KEYCODE(FORWARD),
    DEFINE_KEYCODE(MEDIA_PLAY),
    DEFINE_KEYCODE(MEDIA_PAUSE),
    DEFINE_KEYCODE(MEDIA_CLOSE),
    DEFINE_KEYCODE(MEDIA_EJECT),
    DEFINE_KEYCODE(MEDIA_RECORD),
    DEFINE_KEYCODE(F1),
    DEFINE_KEYCODE(F2),
    DEFINE_KEYCODE(F3),
    DEFINE_KEYCODE(F4),
    DEFINE_KEYCODE(F5),
    DEFINE_KEYCODE(F6),
    DEFINE_KEYCODE(F7),
    DEFINE_KEYCODE(F8),
    DEFINE_KEYCODE(F9),
    DEFINE_KEYCODE(F10),
    DEFINE_KEYCODE(F11),
    DEFINE_KEYCODE(F12),
    DEFINE_KEYCODE(NUM_LOCK),
    DEFINE_KEYCODE(NUMPAD_0),
    DEFINE_KEYCODE(NUMPAD_1),
    DEFINE_KEYCODE(NUMPAD_2),
    DEFINE_KEYCODE(NUMPAD_3),
    DEFINE_KEYCODE(NUMPAD_4),
    DEFINE_KEYCODE(NUMPAD_5),
    DEFINE_KEYCODE(NUMPAD_6),
    DEFINE_KEYCODE(NUMPAD_7),
    DEFINE_KEYCODE(NUMPAD_8),
    DEFINE_KEYCODE(NUMPAD_9),
    DEFINE_KEYCODE(NUMPAD_DIVIDE),
    DEFINE_KEYCODE(NUMPAD_MULTIPLY),
    DEFINE_KEYCODE(NUMPAD_SUBTRACT),
    DEFINE_KEYCODE(NUMPAD_ADD),
    DEFINE_KEYCODE(NUMPAD_DOT),
    DEFINE_KEYCODE(NUMPAD_COMMA),
    DEFINE_KEYCODE(NUMPAD_ENTER),
    DEFINE_KEYCODE(NUMPAD_EQUALS),
    DEFINE_KEYCODE(NUMPAD_LEFT_PAREN),
    DEFINE_KEYCODE(NUMPAD_RIGHT_PAREN),
    DEFINE_KEYCODE(VOLUME_MUTE),
    DEFINE_KEYCODE(INFO),
    DEFINE_KEYCODE(TV),
    DEFINE_KEYCODE(CALENDAR),
    DEFINE_KEYCODE(ZENKAKU_HANKAKU),
    DEFINE_KEYCODE(MUHENKAN),
    DEFINE_KEYCODE(HENKAN),
    DEFINE_KEYCODE(KATAKANA_HIRAGANA),
    DEFINE_KEYCODE(YEN),
    DEFINE_KEYCODE(RO),
    DEFINE_KEYCODE(BRIGHTNESS_DOWN),
    DEFINE_KEYCODE(BRIGHTNESS_UP),
    DEFINE_KEYCODE(SLEEP),
    DEFINE_KEYCODE(WAKEUP),
    DEFINE_KEYCODE(HELP),
    DEFINE_KEYCODE(CUT),
    DEFINE_KEYCODE(COPY),
    DEFINE_KEYCODE(PASTE),
    DEFINE_KEYCODE(REFRESH),
    DEFINE_KEYCODE(NEW),
    DEFINE_KEYCODE(CLOSE),
    DEFINE_KEYCODE(PRINT),
    DEFINE_KEYCODE(F13),
    DEFINE_KEYCODE(F14),
    DEFINE_KEYCODE(F15),
    DEFINE_KEYCODE(F16),
    DEFINE_KEYCODE(F17),
    DEFINE_KEYCODE(F18),
    DEFINE_KEYCODE(F19),
    DEFINE_KEYCODE(F20),
    DEFINE_KEYCODE(F21),
    DEFINE_KEYCODE(F22),
    DEFINE_KEYCODE(F23),
    DEFINE_KEYCODE(F24)
};

const std::unordered_map<std::string, PointerEvent::AxisType> AXES {
    DEFINE_AXIS(X),
    DEFINE_AXIS(Y),
    DEFINE_AXIS(Z),
    DEFINE_AXIS(RX),
    DEFINE_AXIS(RY),
    DEFINE_AXIS(RZ),
    DEFINE_AXIS(THROTTLE),
    DEFINE_AXIS(RUDDER),
    DEFINE_AXIS(WHEEL),
    DEFINE_AXIS(GAS),
    DEFINE_AXIS(BRAKE),
    DEFINE_AXIS(HAT0X),
    DEFINE_AXIS(HAT0Y),
    DEFINE_AXIS(HAT1X),
    DEFINE_AXIS(HAT1Y),
    DEFINE_AXIS(HAT2X),
    DEFINE_AXIS(HAT2Y),
    DEFINE_AXIS(HAT3X),
    DEFINE_AXIS(HAT3Y),
    { "LTRIGGER", PointerEvent::AXIS_TYPE_ABS_BRAKE },
    { "RTRIGGER", PointerEvent::AXIS_TYPE_ABS_GAS },
};
} // namespace

int32_t PropertyNameMapperImpl::MapKey(const std::string &name) const
{
    if (auto iter = KEYCODES.find(name); iter != KEYCODES.cend()) {
        return iter->second;
    }
    return KeyEvent::KEYCODE_UNKNOWN;
}

PointerEvent::AxisType PropertyNameMapperImpl::MapAxis(const std::string &name) const
{
    if (auto iter = AXES.find(name); iter != AXES.cend()) {
        return iter->second;
    }
    return PointerEvent::AXIS_TYPE_UNKNOWN;
}

extern "C" IPropertyNameMapper* CreateInstance(IInputServiceContext *env)
{
    return new PropertyNameMapperImpl();
}

extern "C" void DestroyInstance(IPropertyNameMapper *instance)
{
    if (instance != nullptr) {
        delete instance;
    }
}
} // namespace MMI
} // namespace OHOS