در این سؤال، شما باید `Bale` را پیادهسازی کنید!
# جزئیات پروژه
پروژهی اولیه را از [این لینک](/problemset/assignments/4367/download_problem_initial_project/106382/) دانلود کنید.
متدهایی که باید پیادهسازی کنید به شرح زیر هستند:
+ **متد** `AddUser`: این متد یک کاربر جدید ایجاد میکند. این متد دو مقدار ورودی میگیرد. اولین مقدار، نام کاربری و دومین مقدار، مشخصکنندهی نوع کاربر است. نام کاربری مقداری **یکتا** است و باید دارای طول **بیشتر از** ۳ باشد. همچنین، نام کاربری باید هم شامل حروف انگلیسی و هم ارقام باشد. اگر هر یک از این شرایط برقرار نبود، این متد خطا با پیام `invalid username` را برمیگرداند. در حالتی که خطایی وجود نداشته باشد، این تابع خطا برابر با `nil` و آیدی کاربر را برمیگرداند. آیدی کاربران از عدد ۱ شروع شده و در هر ایجاد کاربر جدید، یک واحد به آن افزوده میشود.
+ **متد** `AddChat`: این متد یک چت جدید ایجاد میکند. این متد چهار ورودی دارد. اولین ورودی، نام چت است. دومین ورودی، نوع چت را مشخص میکند که می تواند از نوع **کانال** یا **گروه** باشد. سومین ورودی، آیدی سازندهی چت است. در نهایت، آخرین ورودی آرایهای از آیدیهاست که نشاندهندهی ادمینهای چت است. **تضمین میشود** که آیدی سازنده حتماً در این آرایه وجود دارد. سازندهی چت نمیتواند بات باشد و در این حالت، متد ارور با پیام `could not create chat` را برمیگرداند. در صورت موفقیتآمیز بودن عملیات، این متد آیدی چت را برمیگرداند. آیدی چتها نیز مانند آیدی کاربران ایجاد میشود.
+ **متد** `SendMessage`: از این متد برای ارسال پیام به یک چت استفاده میشود. اولین ورودی این تابع، کاربری است که میخواهد این پیام را ارسال کند. دومین ورودی، آیدی چتی است که پیام در آن ارسال میشود. آخرین ورودی، متن پیام است. در چتهایی که از نوع کانال هستند، تنها **ادمین**های کانال می توانند پیام ارسال کنند و اگر کاربری که در کانالی ادمین نیست بخواهد در آن کانال پیام ارسال کند، این متد یک ارور با پیام `user could not send message` برمیگرداند. در صورت موفقیتآمیز بودن عملیات، این متد باید آیدی پیام را برگرداند. آیدی پیامها نیز مانند آیدی کاربران ایجاد میشود.
+ **متد** `SendLike`: این متد برای لایک کردن یک پیام خاص کاربرد دارد. هر کاربر هر پیام را تنها یک بار میتواند لایک کند. اگر کاربری بخواهد یک پیام را **بیش از یک بار** لایک کند، باید ارور با پیام `this user has liked this message before` را برگردانید. اگر پیام وجود نداشته باشد (یا شناسهی واردشده نامعتبر باشد)، این متد ارور با پیام `message not found` را برمیگرداند.
+ **متد** `GetNumberOfLikes`: این متد، تعداد لایکهای یک پیام را برمیگرداند. مقدار ارور خروجی باید `nil` باشد. **تضمین میشود** که پیامی با آیدی ورودی در بین پیامها موجود است.
+ **متد** `SetChatAdmin`: این متد یک کاربر مشخص را تبدیل به ادمین در یک چت مشخص میکند. اگر کاربر در حال حاضر ادمین آن چت باشد، این متد یک ارور با پیام `user is already admin` را برمیگرداند.
+ **متد** `GetLastMessage`: این متد، متن پیام و آیدی آخرین پیام در چت مشخص شده را برمیگرداند.
+ **متد** `GetLastUserMessage`: این متد، متن پیام و آیدی آخرین پیامی که کاربر مشخصشده ارسال کرده است را برمیگرداند.
# نکات
+ داده ساختارهای موردنیاز خود را در `BaleImpl` تعریف کنید.
+ برای ساخت یک `Bale` جدید، از `NewBaleImpl` استفاده میشود. مقداردهی اولیهی داده ساختارهای خود را در این تابع قرار دهید.
# آنچه باید آپلود کنید
پس از پیادهسازی موارد خواسته شده، فایل `main.go` را آپلود کنید. در صورتی که از *dependency* خاصی استفاده کردهاید، فایلهای `go.mod` و `go.sum` را بههمراه فایل `main.go` زیپ کرده و آن را آپلود کنید.