// Copyright 2015 Google Inc. All rights reserved
//
// 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.

// +build ignore

#include "find.h"

#include <unistd.h>
#include <string>

#include "fileutil.h"
#include "strutil.h"

int FindUnitTests();

int main(int argc, char* argv[]) {
  if (argc == 1) {
    return FindUnitTests();
  }

  InitFindEmulator();
  string cmd;
  for (int i = 1; i < argc; i++) {
    if (i > 1)
      cmd += ' ';
    cmd += argv[i];
  }
  FindCommand fc;
  if (!fc.Parse(cmd)) {
    fprintf(stderr, "Find emulator does not support this command\n");
    return 1;
  }
  string out;
  if (!FindEmulator::Get()->HandleFind(cmd, fc, Loc(), &out)) {
    fprintf(stderr, "Find emulator does not support this command\n");
    return 1;
  }

  for (StringPiece tok : WordScanner(out)) {
    printf("%.*s\n", SPF(tok));
  }
}

string Run(const string& cmd) {
  string s;
  int ret = RunCommand("/bin/sh", "-c", cmd, RedirectStderr::NONE, &s);

  if (ret != 0) {
    fprintf(stderr, "Failed to run `%s`\n", cmd.c_str());
    exit(ret);
  }

  return s;
}

static bool unit_test_failed = false;

void CompareFind(const string& cmd) {
  string native = Run(cmd);

  FindCommand fc;
  if (!fc.Parse(cmd)) {
    fprintf(stderr, "Find emulator cannot parse `%s`\n", cmd.c_str());
    exit(1);
  }
  string emulated;
  if (!FindEmulator::Get()->HandleFind(cmd, fc, Loc(), &emulated)) {
    fprintf(stderr, "Find emulator cannot parse `%s`\n", cmd.c_str());
    exit(1);
  }

  vector<StringPiece> nativeWords;
  vector<StringPiece> emulatedWords;

  WordScanner(native).Split(&nativeWords);
  WordScanner(emulated).Split(&emulatedWords);

  if (nativeWords != emulatedWords) {
    fprintf(stderr, "Failed to match `%s`:\n", cmd.c_str());

    auto nativeIter = nativeWords.begin();
    auto emulatedIter = emulatedWords.begin();
    fprintf(stderr, "%-20s %-20s\n", "Native:", "Emulated:");
    while (nativeIter != nativeWords.end() ||
           emulatedIter != emulatedWords.end()) {
      fprintf(stderr, " %-20s %-20s\n",
              (nativeIter == nativeWords.end())
                  ? ""
                  : (*nativeIter++).as_string().c_str(),
              (emulatedIter == emulatedWords.end())
                  ? ""
                  : (*emulatedIter++).as_string().c_str());
    }
    fprintf(stderr, "------------------------------------------\n");
    unit_test_failed = true;
  }
}

void ExpectParseFailure(const string& cmd) {
  Run(cmd);

  FindCommand fc;
  if (fc.Parse(cmd)) {
    fprintf(stderr, "Expected parse failure for `%s`\n", cmd.c_str());
    fprintf(stderr, "------------------------------------------\n");
    unit_test_failed = true;
  }
}

int FindUnitTests() {
  Run("rm -rf out/find");
  Run("mkdir -p out/find");
  if (chdir("out/find")) {
    perror("Failed to chdir(out/find)");
    return 1;
  }

  // Set up files under out/find:
  //  drwxr-x--- top
  //  lrwxrwxrwx top/E -> missing
  //  lrwxrwxrwx top/C -> A
  //  -rw-r----- top/a
  //  drwxr-x--- top/A
  //  lrwxrwxrwx top/A/D -> B
  //  -rw-r----- top/A/b
  //  drwxr-x--- top/A/B
  //  -rw-r----- top/A/B/z
  Run("mkdir -p top/A/B");
  Run("cd top && ln -s A C");
  Run("cd top/A && ln -s B D");
  Run("cd top && ln -s missing E");
  Run("touch top/a top/A/b top/A/B/z");

  InitFindEmulator();

  CompareFind("find .");
  CompareFind("find -L .");

  CompareFind("find top/C");
  CompareFind("find top/C/.");
  CompareFind("find -L top/C");
  CompareFind("find -L top/C/.");

  CompareFind("cd top && find C");
  CompareFind("cd top && find -L C");
  CompareFind("cd top/C && find .");

  CompareFind("cd top/C && find D/./z");

  CompareFind("find .//top");

  CompareFind("find top -type f -name 'a*' -o -name \\*b");
  CompareFind("find top \\! -name 'a*'");
  CompareFind("find top \\( -name 'a*' \\)");

  ExpectParseFailure("find top -name a\\*");

  return unit_test_failed ? 1 : 0;
}
