/*
 * Copyright (C) 2017 Open Source Robotics Foundation
 *
 * 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.
 *
*/

#ifndef SDF_TEST_CONFIG_HH_
#define SDF_TEST_CONFIG_HH_

#define IGN_CONFIG_PATH "@CMAKE_BINARY_DIR@/test/conf"
#define IGN_PATH "@IGNITION-TOOLS_BINARY_DIRS@"
#define IGN_TEST_LIBRARY_PATH "${PROJECT_BINARY_DIR}/src:"\
  "@IGNITION-MSGS_LIBRARY_DIRS@:"
#define PROJECT_SOURCE_PATH "${PROJECT_SOURCE_DIR}"
#define PROJECT_BINARY_DIR  "${CMAKE_BINARY_DIR}"
#define SDF_PROTOCOL_VERSION "${SDF_PROTOCOL_VERSION}"
#define SDF_TMP_DIR "tmp-sdf/"

#include "env.hh"

#include <sdf/Filesystem.hh>
namespace sdf
{
  namespace testing
  {
    /// \brief Method to retrieve root directory of project source
    ///
    /// This is used to get various test files
    /// \param[inout] _sourceDir Full path to the source directory
    /// \return True if directory is set correctly, false otherwise
    bool ProjectSourcePath(std::string &_sourceDir)
    {
      // Bazel builds set TEST_SRCDIR
      if(env("TEST_SRCDIR", _sourceDir))
      {
        _sourceDir = sdf::filesystem::append(
            _sourceDir, "__main__", "sdformat");
        return true;
      }
      else
      {
        // CMake builds set PROJECT_SOURCE_PATH
        _sourceDir = PROJECT_SOURCE_PATH;
        return true;
      }

      return false;
    }

    /// \brief Method to retrieve temporary directory for test outputs
    ///
    /// \param[inout] _tmpDir Full path to the temp directory
    /// \return True if directory is set correctly, false otherwise
    bool TestTmpPath(std::string &_tmpDir)
    {
      // Bazel builds set TEST_UNDECLARED_OUTPUTS_DIR
      if (env("TEST_UNDECLARED_OUTPUTS_DIR", _tmpDir))
      {
        return true;
      }
      else
      {
        _tmpDir = sdf::filesystem::append(PROJECT_BINARY_DIR, SDF_TMP_DIR);
        return true;
      }
    }

    /// \brief Method to retrieve temporary home directory for tests
    ///
    /// This will update the contents of the home directory path variable
    /// (HOME on Linux/MacOS, HOMEPATH on Windows) to this newly-set
    /// directory
    /// This additionally sets the HOME and HOMEPATH environment variables
    ///
    /// \param[inout] _homeDir Full path to the home directory
    /// \return True if directory is set correctly, false otherwise
    bool TestSetHomePath(std::string &_homeDir)
    {
      if (env("TEST_UNDECLARED_OUTPUTS_DIR", _homeDir)) 
      {
        return true;
      } 
      else
      {
        _homeDir = PROJECT_BINARY_DIR;
        // Set both for linux and windows
        return setenv("HOME", _homeDir) && setenv("HOMEPATH", _homeDir);
      }
    }

    /// \brief Retrieve a file from the project source directory
    /// \param[in] variable length of arguments relative to the
    ///   repository source directory
    /// \return Full path to requested file
    template <typename... Args>
    std::string SourceFile(Args const &... args)
    {
      std::string dataDir;
      ProjectSourcePath(dataDir);
      return sdf::filesystem::append(dataDir, args...);
    }

    /// \brief Retrieve a file from the test directory
    /// \param[in] variable length of arguments relative to the
    ///   repository test directory
    /// \return Full path to requested test file
    template <typename... Args>
    std::string TestFile(Args const &... args)
    {
      return SourceFile("test", args...);
    }

  }  // namespace testing
}  // namespace sdf

#endif

