import json, strtabs, tables, unittest
from langutils import sameContents
import ../../../main/nim/strawbosspkg/configuration

suite "load and save configuration objects":

  # suite setup & common data
  let testProjDefStr = """{ "name": "dummy-project", "repo":
                            "/non-existent/dir",
                            "cfgFilePath": "strawhat.json",
                            "defaultBranch": "deploy",
                            "envVars": { "VAR1": "value" } }"""

  let testProjDef = ProjectDef(
    name: "dummy-project",
    repo: "/non-existent/dir",
    cfgFilePath: "strawhat.json",
    defaultBranch: "deploy",
    envVars: newStringTable("VAR1", "value", modeCaseInsensitive))


  test "parseProjectDef":
    let pd = parseProjectDef(parseJson(testProjDefStr))

    check:
      pd.name == "dummy-project"
      pd.repo == "/non-existent/dir"
      pd.cfgFilePath == "strawhat.json"
      pd.defaultBranch == "deploy"
      pd.envVars.len == 1
      pd.envVars.hasKey("VAR1")
      pd.envVars["VAR1"] == "value"

  test "ProjectDef ==":
    let pd1 = parseProjectDef(parseJson(testProjDefStr))

    check pd1 == testProjDef

  test "ProjectDef != (name)":
    var pd1 = testProjDef
    pd1.name = "different"
    check pd1 != testProjDef

  test "ProjectDef != (repo)":
    var pd1 = testProjDef
    pd1.repo = "different"
    check pd1 != testProjDef

  test "ProjectDef != (cfgFilePath)":
    var pd1 = testProjDef
    pd1.cfgFilePath = "different"
    check pd1 != testProjDef

  test "ProjectDef != (defaultBranch)":
    var pd1 = testProjDef
    pd1.defaultBranch = "different"
    check pd1 != testProjDef

  test "loadStrawBossConfig":
    let cfg = loadStrawBossConfig("src/test/json/strawboss.config.json")
    let expectedUsers = @[UserRef(name: "bob@builder.com", hashedPwd: "testvalue"),
                          UserRef(name: "sam@sousa.com", hashedPwd: "testvalue")]
    let expectedProjects = @[
      ProjectDef(name: "dummy-project",
                 repo: "/non-existent/dir",
                 defaultBranch: "deploy",
                 cfgFilePath: "strawhat.json",
                 envVars: newStringTable("VAR1", "value", modeCaseSensitive)),
      ProjectDef(name: "test-project",
                 repo: "",
                 defaultBranch: "master",
                 cfgFilePath: "strawboss.json",
                 envVars: newStringTable(modeCaseSensitive))]

    check:
      cfg.artifactsRepo == "artifacts"
      cfg.authSecret == "change me"
      cfg.pwdCost == 11
      sameContents(expectedUsers, cfg.users)
      sameContents(expectedProjects, cfg.projects)

  test "loadProjectConfig":
    let pc = loadProjectConfig("src/test/json/dummy-project.config.json")

    check:
      pc.name == "dummy-project"
      pc.versionCmd == "git describe --all --always"
      pc.steps.len == 2

      # Explicitly set properties
      pc.steps["build"].name == "build"
      pc.steps["build"].dontSkip == true
      pc.steps["build"].stepCmd == "cust-build"
      pc.steps["build"].workingDir == "dir1"
      sameContents(pc.steps["build"].artifacts, @["bin1", "doc1"])
      sameContents(pc.steps["build"].depends, @["test"])
      sameContents(pc.steps["build"].expectedEnv, @["VAR1"])
      sameContents(pc.steps["build"].cmdInput, @["test", "this"])

      # Step with defaulted properties
      pc.steps["test"].name == "test"
      pc.steps["test"].dontSkip == false
      pc.steps["test"].stepCmd == "true"
      pc.steps["test"].workingDir == "."
      sameContents(pc.steps["test"].artifacts, @[])
      sameContents(pc.steps["test"].depends, @[])
      sameContents(pc.steps["test"].expectedEnv, @[])
      sameContents(pc.steps["test"].cmdInput, @[])

  test "serialze StrawBossConfig to/from string":
    let cfg = loadStrawBossConfig("src/test/json/strawboss.config.json")
    let cfgStr = $cfg
    check cfg == parseStrawBossConfig(parseJson(cfgStr))

  test "loadBuildStatus":
    let st = loadBuildStatus("src/test/json/test-status.json")

    check:
      st.state == "failed"
      st.details == "some very good reason"