/*
 * Copyright (c) 2018-2019 Atmosphère-NX
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope 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 this program.  If not, see .
 */
#include 
#include 
#include 
#include "set_mitm_service.hpp"
#include "set_shim.h"
void SetMitmService::PostProcess(IMitmServiceObject *obj, IpcResponseContext *ctx) {
    /* No commands need postprocessing. */
}
bool SetMitmService::IsValidLanguageCode(u64 lang_code) {
    static constexpr u64 s_valid_language_codes[] = {
        LanguageCode_Japanese,
        LanguageCode_AmericanEnglish,
        LanguageCode_French,
        LanguageCode_German,
        LanguageCode_Italian,
        LanguageCode_Spanish,
        LanguageCode_Chinese,
        LanguageCode_Korean,
        LanguageCode_Dutch,
        LanguageCode_Portuguese,
        LanguageCode_Russian,
        LanguageCode_Taiwanese,
        LanguageCode_BritishEnglish,
        LanguageCode_CanadianFrench,
        LanguageCode_LatinAmericanSpanish,
        LanguageCode_SimplifiedChinese,
        LanguageCode_TraditionalChinese,
    };
    size_t num_language_codes = sts::util::size(s_valid_language_codes);
    if (GetRuntimeFirmwareVersion() < FirmwareVersion_400) {
        /* 4.0.0 added simplified and traditional chinese. */
        num_language_codes -= 2;
    }
    for (size_t i = 0; i < num_language_codes; i++) {
        if (lang_code == s_valid_language_codes[i]) {
            return true;
        }
    }
    return false;
}
bool SetMitmService::IsValidRegionCode(u32 region_code) {
    return region_code < RegionCode_Max;
}
Result SetMitmService::EnsureLocale() {
    std::scoped_lock lk(this->lock);
    if (!this->got_locale) {
        std::memset(&this->locale, 0xCC, sizeof(this->locale));
        if (this->title_id == sts::ncm::TitleId::Ns) {
            u64 app_pid = 0;
            u64 app_tid = 0;
            R_TRY(pmdmntGetApplicationPid(&app_pid));
            R_TRY(pminfoGetTitleId(&app_tid, app_pid));
            this->locale = Utils::GetTitleOverrideLocale(app_tid);
        } else {
            this->locale = Utils::GetTitleOverrideLocale(static_cast(this->title_id));
            this->got_locale = true;
        }
    }
    return ResultSuccess;
}
Result SetMitmService::GetLanguageCode(Out out_lang_code) {
    this->EnsureLocale();
    if (!IsValidLanguageCode(this->locale.language_code)) {
        return ResultAtmosphereMitmShouldForwardToSession;
    }
    out_lang_code.SetValue(this->locale.language_code);
    return ResultSuccess;
}
Result SetMitmService::GetRegionCode(Out out_region_code) {
    this->EnsureLocale();
    if (!IsValidRegionCode(this->locale.region_code)) {
        return ResultAtmosphereMitmShouldForwardToSession;
    }
    out_region_code.SetValue(this->locale.region_code);
    return ResultSuccess;
}
Result SetMitmService::GetAvailableLanguageCodes(OutPointerWithClientSize out_language_codes, Out out_count) {
    return setGetAvailableLanguageCodesFwd(this->forward_service.get(), out_count.GetPointer(), out_language_codes.pointer, out_language_codes.num_elements);
}