// Copyright 2014 The Bazel Authors. 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.

package com.google.devtools.build.lib.skylark.util;


import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.analysis.skylark.SkylarkModules;
import com.google.devtools.build.lib.analysis.skylark.SkylarkRuleContext;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.packages.BazelStarlarkContext;
import com.google.devtools.build.lib.packages.SymbolGenerator;
import com.google.devtools.build.lib.rules.platform.PlatformCommon;
import com.google.devtools.build.lib.syntax.Runtime;
import com.google.devtools.build.lib.syntax.SkylarkUtils;
import com.google.devtools.build.lib.syntax.SkylarkUtils.Phase;
import com.google.devtools.build.lib.syntax.StarlarkThread;
import com.google.devtools.build.lib.syntax.StarlarkThread.GlobalFrame;
import com.google.devtools.build.lib.syntax.util.EvaluationTestCase;
import com.google.devtools.build.lib.testutil.TestConstants;
import org.junit.Before;

/**
 * A class to contain the common functionality for analysis-phase Skylark tests. The less stuff
 * here, the better.
 */
public abstract class SkylarkTestCase extends BuildViewTestCase {

  protected EvaluationTestCase ev;

  // Subclasses must call this method after change SkylarkSemantics (among other things).
  @Before
  public final void reset() throws Exception {
    ev = createEvaluationTestCase();
  }

  private EvaluationTestCase createEvaluationTestCase() throws Exception {
    // Set up globals.
    ImmutableMap.Builder<String, Object> env = ImmutableMap.builder();
    SkylarkModules.addSkylarkGlobalsToBuilder(env);
    Runtime.setupSkylarkLibrary(env, new PlatformCommon());
    GlobalFrame globals = GlobalFrame.createForBuiltins(env.build());

    EvaluationTestCase ev =
        new EvaluationTestCase() {
          @Override
          public StarlarkThread newStarlarkThread() throws Exception {
            StarlarkThread thread =
                StarlarkThread.builder(mutability)
                    .setSemantics(getSkylarkSemantics())
                    .setEventHandler(getEventHandler())
                    .setGlobals(
                        globals.withLabel(
                            Label.parseAbsoluteUnchecked("//test:label", /*defaultToMain=*/ false)))
                    .build();

            SkylarkUtils.setPhase(thread, Phase.LOADING);

            // This StarlarkThread has no PackageContext, so attempts to create a rule will fail.
            // Rule creation is tested by SkylarkIntegrationTest.

            new BazelStarlarkContext(
                    TestConstants.TOOLS_REPOSITORY,
                    /*fragmentNameToClass=*/ null,
                    /*repoMapping=*/ ImmutableMap.of(),
                    new SymbolGenerator<>(new Object()),
                    /*analysisRuleLabel=*/ null)
                .storeInThread(thread);

            return thread;
          }
        };
    ev.initialize();
    return ev;
  }

  protected final Object eval(String... input) throws Exception {
    return ev.eval(input);
  }

  protected final void update(String name, Object value) throws Exception {
    ev.update(name, value);
  }

  protected final Object lookup(String name) throws Exception {
    return ev.lookup(name);
  }

  protected final void checkEvalErrorContains(String msg, String... input) throws Exception {
    ev.checkEvalErrorContains(msg, input);
  }

  protected final SkylarkRuleContext createRuleContext(String label) throws Exception {
    return new SkylarkRuleContext(getRuleContextForSkylark(getConfiguredTarget(label)), null,
        getSkylarkSemantics());
  }

  // Disable BuildViewTestCase's overload to avoid unintended calls.
  @Override
  protected final Event checkError(String x, String y) throws Exception {
    throw new IllegalStateException("wrong method");
  }

}
