// Copyright 2017-2020 The Verible Authors.
//
// 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 "common/strings/obfuscator.h"

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "common/util/bijective_map.h"
#include "common/util/logging.h"

namespace verible {
namespace {

static char Rot13(char c) {
  if ((c >= 'a' && c <= 'm') || (c >= 'A' && c <= 'M'))
    return c + 13;
  else if ((c >= 'n' && c <= 'z') || (c >= 'N' && c <= 'Z'))
    return c - 13;
  else
    return c;
}

// Non-random generator, just for the sake of testing.
static std::string RotateGenerator(absl::string_view input) {
  std::string s(input);
  for (auto& ch : s) ch = Rot13(ch);
  return s;
}

TEST(ObfuscatorTest, Construction) {
  Obfuscator ob(RotateGenerator);
  EXPECT_TRUE(ob.GetTranslator().empty());
}

TEST(ObfuscatorTest, Transform) {
  Obfuscator ob(RotateGenerator);
  const auto& tran = ob.GetTranslator();
  // repeat same string
  for (int i = 0; i < 2; ++i) {
    const auto str = ob("cat");
    EXPECT_EQ(str, "png");
    EXPECT_EQ(tran.size(), 1);
    EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_forward("cat")), "png");
    EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_reverse("png")), "cat");
  }
  for (int i = 0; i < 2; ++i) {
    const auto str = ob("Dog");
    EXPECT_EQ(str, "Qbt");
    EXPECT_EQ(tran.size(), 2);
    EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_forward("cat")), "png");
    EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_reverse("png")), "cat");
    EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_forward("Dog")), "Qbt");
    EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_reverse("Qbt")), "Dog");
  }
}

TEST(ObfuscatorTest, Encode) {
  Obfuscator ob(RotateGenerator);
  ob.encode("cat", "sheep");
  const auto& tran = ob.GetTranslator();
  EXPECT_EQ(tran.size(), 1);
  EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_forward("cat")), "sheep");
  EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_reverse("sheep")), "cat");
  // repeat same string
  for (int i = 0; i < 2; ++i) {
    const auto str = ob("cat");
    EXPECT_EQ(str, "sheep");
    EXPECT_EQ(tran.size(), 1);
    EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_forward("cat")), "sheep");
    EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_reverse("sheep")), "cat");
  }
  for (int i = 0; i < 2; ++i) {
    const auto str = ob("dog");
    EXPECT_EQ(str, "qbt");
    EXPECT_EQ(tran.size(), 2);
    EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_forward("cat")), "sheep");
    EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_reverse("sheep")), "cat");
    EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_forward("dog")), "qbt");
    EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_reverse("qbt")), "dog");
  }
}

TEST(ObfuscatorTest, DecodeMode) {
  Obfuscator ob(RotateGenerator);
  EXPECT_FALSE(ob.is_decoding());
  ob.set_decode_mode(true);
  EXPECT_TRUE(ob.is_decoding());
  ob.set_decode_mode(false);
  EXPECT_FALSE(ob.is_decoding());
}

TEST(ObfuscatorTest, DecodeModeDoesNotAddEntries) {
  Obfuscator ob(RotateGenerator);
  ob.set_decode_mode(true);
  EXPECT_TRUE(ob.is_decoding());
  EXPECT_TRUE(ob.GetTranslator().empty());
  EXPECT_EQ(ob("dog"), "dog");  // unrecognized id, unchanged
  EXPECT_TRUE(ob.GetTranslator().empty());

  // can still manually add entries
  EXPECT_TRUE(ob.encode("shark", "snake"));
  EXPECT_EQ(ob.GetTranslator().size(), 1);
  EXPECT_EQ(ob("snake"), "shark");  // decoded
  EXPECT_EQ(ob.GetTranslator().size(), 1);
  EXPECT_EQ(ob("cow"), "cow");
  EXPECT_EQ(ob.GetTranslator().size(), 1);
}

TEST(ObfuscatorTest, SaveMap) {
  Obfuscator ob(RotateGenerator);
  EXPECT_EQ(ob.save(), "");
  EXPECT_EQ(ob("cat"), "png");
  EXPECT_EQ(ob.save(), "cat png\n");
  EXPECT_EQ(ob("zzz"), "mmm");
  EXPECT_EQ(ob.save(), "cat png\nzzz mmm\n");
}

TEST(ObfuscatorTest, LoadMap) {
  {
    Obfuscator ob(RotateGenerator);
    const auto status = ob.load("");
    EXPECT_TRUE(status.ok()) << status.message();
  }
  {
    Obfuscator ob(RotateGenerator);
    const auto status = ob.load("cat dog");
    EXPECT_TRUE(status.ok()) << status.message();
    EXPECT_EQ(ob("cat"), "dog");
  }
  {
    Obfuscator ob(RotateGenerator);
    const auto status = ob.load("cat dog\n");
    EXPECT_TRUE(status.ok()) << status.message();
    EXPECT_EQ(ob("cat"), "dog");
  }
  {
    Obfuscator ob(RotateGenerator);
    const auto status = ob.load("cat\n");  // malformed line
    EXPECT_FALSE(status.ok());
    EXPECT_EQ(status.code(), absl::StatusCode::kInvalidArgument);
  }
}

TEST(IdentifierObfuscatorTest, Transform) {
  IdentifierObfuscator ob;
  const auto& tran = ob.GetTranslator();
  // repeat same string
  for (int i = 0; i < 2; ++i) {
    const auto str = ob("cat");  // str is random
    EXPECT_EQ(tran.size(), 1);
    EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_forward("cat")), str);
    EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_reverse(std::string(str))), "cat");
  }
  for (int i = 0; i < 2; ++i) {
    const auto str = ob("dog");  // str is random
    EXPECT_EQ(tran.size(), 2);
    EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_forward("dog")), str);
    EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_reverse(std::string(str))), "dog");
  }
  for (int i = 0; i < 2; ++i) {
    const auto str = ob("cat");  // str is random
    EXPECT_EQ(tran.size(), 2);
    EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_forward("cat")), str);
    EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_reverse(std::string(str))), "cat");
  }
}

TEST(IdentifierObfuscatorTest, EncodeInvalid) {
  IdentifierObfuscator ob;
  EXPECT_DEATH(ob.encode("cat", "sheep"), "");  // mismatch length
}

TEST(IdentifierObfuscatorTest, EncodeValidTransform) {
  IdentifierObfuscator ob;
  ob.encode("cat", "cow");
  const auto& tran = ob.GetTranslator();
  // repeat same string
  for (int i = 0; i < 2; ++i) {
    const auto str = ob("cat");
    EXPECT_EQ(str, "cow");
    EXPECT_EQ(tran.size(), 1);
    EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_forward("cat")), str);
    EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_reverse(std::string(str))), "cat");
  }
  for (int i = 0; i < 2; ++i) {
    const auto str = ob("Dog");  // str is random
    EXPECT_EQ(tran.size(), 2);
    EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_forward("Dog")), str);
    EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_reverse(std::string(str))), "Dog");
  }
  for (int i = 0; i < 2; ++i) {
    const auto str = ob("cat");
    EXPECT_EQ(str, "cow");
    EXPECT_EQ(tran.size(), 2);
    EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_forward("cat")), str);
    EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_reverse(std::string(str))), "cat");
  }
}

}  // namespace
}  // namespace verible
