// Copyright 2012 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.

#include "includes_normalize.h"

#include "string_piece.h"
#include "util.h"

#include <algorithm>
#include <iterator>
#include <sstream>

#include <windows.h>

namespace {

/// Return true if paths a and b are on the same Windows drive.
bool SameDrive(StringPiece a, StringPiece b)  {
  char a_absolute[_MAX_PATH];
  char b_absolute[_MAX_PATH];
  GetFullPathName(a.AsString().c_str(), sizeof(a_absolute), a_absolute, NULL);
  GetFullPathName(b.AsString().c_str(), sizeof(b_absolute), b_absolute, NULL);
  char a_drive[_MAX_DIR];
  char b_drive[_MAX_DIR];
  _splitpath(a_absolute, a_drive, NULL, NULL, NULL);
  _splitpath(b_absolute, b_drive, NULL, NULL, NULL);
  return _stricmp(a_drive, b_drive) == 0;
}

}  // anonymous namespace

string IncludesNormalize::Join(const vector<string>& list, char sep) {
  string ret;
  for (size_t i = 0; i < list.size(); ++i) {
    ret += list[i];
    if (i != list.size() - 1)
      ret += sep;
  }
  return ret;
}

vector<string> IncludesNormalize::Split(const string& input, char sep) {
  vector<string> elems;
  stringstream ss(input);
  string item;
  while (getline(ss, item, sep))
    elems.push_back(item);
  return elems;
}

string IncludesNormalize::ToLower(const string& s) {
  string ret;
  transform(s.begin(), s.end(), back_inserter(ret), ::tolower);
  return ret;
}

string IncludesNormalize::AbsPath(StringPiece s) {
  char result[_MAX_PATH];
  GetFullPathName(s.AsString().c_str(), sizeof(result), result, NULL);
  for (char* c = result; *c; ++c)
    if (*c == '\\')
      *c = '/';
  return result;
}

string IncludesNormalize::Relativize(StringPiece path, const string& start) {
  vector<string> start_list = Split(AbsPath(start), '/');
  vector<string> path_list = Split(AbsPath(path), '/');
  int i;
  for (i = 0; i < static_cast<int>(min(start_list.size(), path_list.size()));
       ++i) {
    if (ToLower(start_list[i]) != ToLower(path_list[i]))
      break;
  }

  vector<string> rel_list;
  for (int j = 0; j < static_cast<int>(start_list.size() - i); ++j)
    rel_list.push_back("..");
  for (int j = i; j < static_cast<int>(path_list.size()); ++j)
    rel_list.push_back(path_list[j]);
  if (rel_list.size() == 0)
    return ".";
  return Join(rel_list, '/');
}

string IncludesNormalize::Normalize(const string& input,
                                    const char* relative_to) {
  char copy[_MAX_PATH];
  size_t len = input.size();
  strncpy(copy, input.c_str(), input.size() + 1);
  string err;
  unsigned int slash_bits;
  if (!CanonicalizePath(copy, &len, &slash_bits, &err))
    Warning("couldn't canonicalize '%s': %s\n", input.c_str(), err.c_str());
  StringPiece partially_fixed(copy, len);

  string curdir;
  if (!relative_to) {
    curdir = AbsPath(".");
    relative_to = curdir.c_str();
  }
  if (!SameDrive(partially_fixed, relative_to))
    return partially_fixed.AsString();
  return Relativize(partially_fixed, relative_to);
}
