const { Haiku } = require('../domain/types/Haiku');

class FakeHaikuDB {
  async init() {
    this.haikuMap = {};
    return new Promise((resolve) => {
      resolve();
    });
  }

  /* eslint-disable class-methods-use-this */
  async close() {
    return new Promise((resolve) => {
      resolve();
    });
  }
  /* eslint-enable class-methods-use-this */

  createHaiku(haikuInput) {
    const { serverId } = haikuInput;

    if (!(serverId in this.haikuMap)) {
      this.haikuMap[serverId] = { count: 0 };
    }
    const id = this.haikuMap[serverId].count;
    this.haikuMap[serverId][id] = {
      id,
      lines: haikuInput.lines,
      authors: haikuInput.authors,
      timestamp: new Date(),
      channel: haikuInput.channelId,
      server: serverId,
    };
    this.haikuMap[serverId].count += 1;
    return this.getHaiku(serverId, id);
  }

  getHaiku(serverId, id) {
    return new Promise((resolve, reject) => {
      if (!this.haikuMap[serverId] || !this.haikuMap[serverId][id]) {
        reject(new Error(`No haiku with id ${id} found in server ${serverId}`));
      }
      resolve(new Haiku(id, this.haikuMap[serverId][id]));
    });
  }

  clearHaiku(serverId, id) {
    if (serverId in this.haikuMap) {
      delete this.haikuMap[serverId][id];
    }
  }

  clearAllHaikus() {
    this.haikuMap = {};
  }

  /* eslint-disable class-methods-use-this */
  getChannel(id) {
    return { id };
  }

  getServer(id) {
    return { id };
  }
  /* eslint-enable class-methods-use-this */
}

exports.FakeHaikuDB = FakeHaikuDB;

@@ -107,16 +107,36 @@
 p = %7B%7D;%0A
+    this.count = 0;%0A
     retu
@@ -414,166 +414,17 @@
 nst 
-%7B serverId %7D = haikuInput;%0A%0A    if (!(serverId in this.haikuMap)) %7B%0A      this.haikuMap%5BserverId%5D = %7B count: 0 %7D;%0A    %7D%0A    const id = this.haikuMap%5BserverId%5D
+id = this
 .cou
@@ -445,26 +445,16 @@
 aikuMap%5B
-serverId%5D%5B
 id%5D = %7B%0A
@@ -609,16 +609,27 @@
 server: 
+haikuInput.
 serverId
@@ -650,27 +650,8 @@
 his.
-haikuMap%5BserverId%5D.
 coun
@@ -675,32 +675,43 @@
 n this.getHaiku(
+haikuInput.
 serverId, id);%0A 
@@ -816,22 +816,15 @@
 Map%5B
-serverI
+i
 d%5D %7C%7C 
-!
 this
@@ -829,32 +829,47 @@
 is.haikuMap%5B
+id%5D.server !== 
 serverId
 %5D%5Bid%5D) %7B%0A   
@@ -856,21 +856,16 @@
 serverId
-%5D%5Bid%5D
 ) %7B%0A    
@@ -991,26 +991,16 @@
 aikuMap%5B
-serverId%5D%5B
 id%5D));%0A 
@@ -1048,23 +1048,17 @@
     if (
-serverI
+i
 d in thi
@@ -1071,108 +1071,1058 @@
 uMap
-) %7B%0A      delete this.haikuMap%5BserverId%5D%5Bid%5D
+ && this.haikuMap%5Bid%5D.server === serverId) %7B%0A      delete this.haikuMap%5Bid%5D;%0A    %7D%0A  %7D%0A%0A  clearAllHaikus() %7B%0A    this.haikuMap = %7B%7D;%0A  %7D%0A%0A  searchHaikus(keywords) %7B%0A    return new Promise((resolve, reject) =%3E %7B%0A      if (keywords.length === 0) %7B%0A        reject(new Error('no keywords given'));%0A      %7D%0A%0A      const validKeywordsRegex = /%5E%5Cw+%5C*?$/
 ;%0A    
+ 
-%7D%0A  %7D%0A%0A  clearAllHaikus() %7B%0A    this.haikuMap = %7B%7D
+ const invalidKeywords = keywords.filter(keyword =%3E !validKeywordsRegex.test(keyword));%0A%0A      if (invalidKeywords.length %3E 0) %7B%0A        reject(new Error(%60Invalid keywords: $%7BinvalidKeywords%7D%60));%0A      %7D%0A%0A      const result = Object.values(this.haikuMap)%0A        .filter((haiku) =%3E %7B%0A          const tokens = haiku.lines.join('%5Cn').split(/%5CW/);%0A          return keywords.some((keyword) =%3E %7B%0A            if (keyword.endsWith('*')) %7B%0A              return tokens.some(token =%3E token.startsWith(keyword.slice(0, -1)));%0A            %7D%0A            return tokens.includes(keyword);%0A          %7D);%0A        %7D)%0A        .map(haiku =%3E new Haiku(haiku.id, this.haikuMap%5Bhaiku.id%5D));%0A      resolve(result);%0A    %7D)
 ;%0A  

Add search command to fake DB and refactor it Refactor to make haikumap use id as key instead of server -> id