require "spec_helper"
require "json"

module Omnibus
  describe DependencyInformation do

    let(:install_dir) { File.join(tmp_path, "install_dir") }
    let(:output_location) { File.join(install_dir, "dependency_licenses.json") }

    let(:project) do
      Project.new.tap do |project|
        project.name("test-project")
        project.build_version("1.0.0")
        project.install_dir(install_dir)
      end
    end

    let(:private_code) do
      Software.new(project, "private_code.rb").evaluate do
        name "private_code"
        default_version "1.7.2"
      end
    end

    let(:zlib) do
      Software.new(project, "zlib.rb").evaluate do
        name "zlib"
        default_version "1.7.2"
        license "Zlib"
        license_file "LICENSE"
      end
    end

    let(:snoopy) do
      Software.new(project, "snoopy.rb").evaluate do
        name "snoopy"
        default_version "1.0.0"
        license "GPL v2"
      end
    end

    let(:zlib_license) do
      <<~EOF
        (C) 1995-2017 Jean-loup Gailly and Mark Adler

          This software is provided 'as-is', without any express or implied
          warranty.  In no event will the authors be held liable for any damages
          arising from the use of this software.

          Permission is granted to anyone to use this software for any purpose,
          including commercial applications, and to alter it and redistribute it
          freely, subject to the following restrictions:

          1. The origin of this software must not be misrepresented; you must not
            claim that you wrote the original software. If you use this software
            in a product, an acknowledgment in the product documentation would be
            appreciated but is not required.
          2. Altered source versions must be plainly marked as such, and must not be
            misrepresented as being the original software.
          3. This notice may not be removed or altered from any source distribution.

          Jean-loup Gailly        Mark Adler
          jloup@gzip.org          madler@alumni.caltech.edu

        If you use the zlib library in a product, we would appreciate *not* receiving
        lengthy legal documents to sign.  The sources are provided for free but without
        warranty of any kind.  The library has been entirely written by Jean-loup
        Gailly and Mark Adler; it does not include third-party code.

        If you redistribute modified sources, we would appreciate that you include in
        the file ChangeLog history information documenting your changes.  Please read
        the FAQ for more information on the distribution of modified source versions.
      EOF
    end

    before do
      FileUtils.mkdir_p(install_dir)
      allow(File).to receive(:exist?).and_call_original
      allow(File).to receive(:read).and_call_original
      allow(File).to receive(:exist?).with(/zlib-LICENSE/).and_return(true)
      allow(File).to receive(:read).with(/zlib-LICENSE/).and_return(zlib_license)
    end

    def generate_information
      project.library.component_added(snoopy)
      project.library.component_added(zlib)
      project.library.component_added(private_code)

      DependencyInformation.process!(project)
    end

    describe "without explicit csv files" do

      it "creates depdendency_licenses.json file" do
        generate_information
        expect(File).to exist(output_location)
      end

      it "dependency_licenses.json file has correct contents" do
        content = [
          {
            "name": "snoopy",
            "dependencies": [],
            "version": "1.0.0",
            "license": "GPL v2",
            "license_texts": [],
          },
          {
            "name": "zlib",
            "dependencies": [],
            "version": "1.7.2",
            "license": "Zlib",
            "license_texts": [zlib_license],
          },
          {
            "name": "private_code",
            "dependencies": [],
            "version": "1.7.2",
            "license": "Unspecified",
            "license_texts": [],
          },
        ]
        generate_information
        json_output = JSON.parse(File.open(output_location).read, symbolize_names: true)
        expect(json_output).to eq(content)
      end
    end

    describe "with explicit csv files" do
      let(:snoopy_json) do
        <<~EOF
        {
          "dependencies": [
            {
              "name": "RedCloth",
              "version": "4.3.2",
              "licenses": ["MIT"]
            },
            {
              "name": "yauzl",
              "version": "2.4.1",
              "licenses": ["MIT"]
            },
            {
              "name": "yargs-parser",
              "version": "4.2.1",
              "licenses": ["ISC"]
            }
          ]
        }
        EOF
      end

      let(:zlib_json) do
        <<~EOF
        {
          "dependencies": [
            {
              "name": "virtus",
              "version": "1.0.5",
              "licenses": ["MIT"]
            },
            {
              "name": "yauzl",
              "version": "2.4.1",
              "licenses": ["MIT"]
            }
          ]
        }
        EOF
      end

      it "creates depdendency_licenses.json file" do
        generate_information
        expect(File).to exist(output_location)
      end

      it "dependency_licenses.json file has contents from csv files also" do
        allow(Dir).to receive(:glob).and_return(["snoopy.json", "zlib.json"])
        allow(File).to receive(:open).and_call_original
        allow(File).to receive(:read).with("snoopy.json").and_return(snoopy_json)
        allow(File).to receive(:read).with("zlib.json").and_return(zlib_json)
        content = [
          {
            "name": "snoopy",
            "dependencies": [
              {
                "name": "RedCloth",
                "version": "4.3.2",
                "license": "MIT",
                "license_texts": [],
              },
              {
                "name": "yauzl",
                "version": "2.4.1",
                "license": "MIT",
                "license_texts": [],
              },
              {
                "name": "yargs-parser",
                "version": "4.2.1",
                "license": "ISC",
                "license_texts": [],
              },
            ],
            "version": "1.0.0",
            "license": "GPL v2",
            "license_texts": [],
          },
          {
            "name": "zlib",
            "dependencies": [
              {
                "name": "virtus",
                "version": "1.0.5",
                "license": "MIT",
                "license_texts": [],
              },
              {
                "name": "yauzl",
                "version": "2.4.1",
                "license": "MIT",
                "license_texts": [],
              },
            ],
            "version": "1.7.2",
            "license": "Zlib",
            "license_texts": [zlib_license],
          },
          {
            "name": "private_code",
            "dependencies": [],
            "version": "1.7.2",
            "license": "Unspecified",
            "license_texts": [],
          },
        ]
        generate_information
        json_output = JSON.parse(File.open(output_location).read, symbolize_names: true)
        expect(json_output).to eq(content)
      end
    end
  end
end
