#include "info.h"

#include <library/cpp/protobuf/util/pb_io.h>
#include <util/datetime/base.h>
#include <util/folder/path.h>
#include <util/generic/algorithm.h>
#include <util/generic/vector.h>
#include <util/stream/file.h>

namespace NFusion {
    namespace {
        inline TString RestorePath(const TString& path, const TFsPath& root) {
            if (!path) {
                return Default<TString>();
            }

            TFsPath fsPath(path);
            fsPath.Fix();
            if (fsPath.IsRelative()) {
                return root / fsPath;
            } else {
                return fsPath;
            }
        }

        void RestorePaths(NRtDoc::TBuilderTask& task, const TFsPath& projectRoot) {
            for (size_t i = 0; i < task.InputsSize(); ++i) {
                NRtDoc::TBuilderTask::TBuilderInput* input = task.MutableInputs(i);
                input->SetSrcDir(RestorePath(input->GetSrcDir(), projectRoot));
                input->SetSrcMapping(RestorePath(input->GetSrcMapping(), projectRoot));
            }

            if (task.HasOutput()) {
                NRtDoc::TBuilderTask::TBuilderOutput* output = task.MutableOutput();
                output->SetTrgDir(RestorePath(output->GetTrgDir(), projectRoot));
                output->SetTempDir(RestorePath(output->GetTempDir(), projectRoot));
            }
        }
    }

    void DumpBuilderTask(const NRtDoc::TBuilderTask& task, const TString& protoTextFile) {
        const TFsPath outputPath = protoTextFile ? TFsPath(protoTextFile) : TFsPath(task.GetOutput().GetTrgDir()) / "builder_task.pb.txt";
        TVector<TString> allPaths;
        for (size_t i = 0; i < task.InputsSize(); ++i) {
            allPaths.push_back(task.GetInputs(i).GetSrcDir());
            allPaths.push_back(task.GetInputs(i).GetSrcMapping());
        }
        allPaths.push_back(task.GetOutput().GetTrgDir());
        allPaths.push_back(task.GetOutput().GetTempDir());

        NRtDoc::TBuilderTask taskToPrint;
        taskToPrint.CopyFrom(task);

        TFileOutput file(outputPath);
        file.SetFinishPropagateMode(true);

        file << "# Created at:   " << Now() << Endl;
        SerializeToTextFormat(taskToPrint, file);
        file.Finish();
    }

    void RestoreBuilderTask(NRtDoc::TBuilderTask& task, const TString& protoTextFile, const TString& projectRoot) {
        task.Clear();

        TFileInput file(protoTextFile);
        ParseFromTextFormat(file, task, EParseFromTextFormatOption::AllowUnknownField);
        if (projectRoot) {
            RestorePaths(task, projectRoot);
        }
    }
}
