/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * 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.doclava;

import com.google.clearsilver.jsilver.data.Data;

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

public class CompatInfo {

  public static class CompatChange {
    public final String name;
    public final long id;
    public final String description;
    public final String definedInClass;
    public final String sourceFile;
    public final int sourceLine;
    public final int enableAfterTargetSdk;

    CompatChange(String name, long id, String description, String definedInClass,
        String sourceFile, int sourceLine, int enableAfterTargetSdk) {
      this.name = name;
      this.id = id;
      this.description = description;
      this.definedInClass = definedInClass;
      this.sourceFile = sourceFile;
      this.sourceLine = sourceLine;
      this.enableAfterTargetSdk = enableAfterTargetSdk;
    }

    static class Builder {
      private String mName;
      private long mId;
      private String mDescription;
      private String mDefinedInClass;
      private String mSourceFile;
      private int mSourceLine;
      private int mEnableAfterTargetSdk;

      CompatChange build() {
        return new CompatChange(
            mName, mId, mDescription, mDefinedInClass, mSourceFile, mSourceLine,
            mEnableAfterTargetSdk);
      }

      Builder name(String name) {
        mName = name;
        return this;
      }

      Builder id(long id) {
        mId = id;
        return this;
      }

      Builder description(String description) {
        mDescription = description;
        return this;
      }

      Builder definedInClass(String definedInClass) {
        mDefinedInClass = definedInClass;
        return this;
      }

      Builder sourcePosition(String sourcePosition) throws SAXException {
        if (sourcePosition != null) {
          int colonPos = sourcePosition.indexOf(":");
          if (colonPos == -1) {
            throw new SAXException("Invalid source position: " + sourcePosition);
          }
          mSourceFile = sourcePosition.substring(0, colonPos);
          try {
            mSourceLine = Integer.parseInt(sourcePosition.substring(colonPos + 1));
          } catch (NumberFormatException nfe) {
            throw new SAXException("Invalid source position: " + sourcePosition, nfe);
          }
        }
        return this;
      }

      Builder enableAfterTargetSdk(String enableAfter) throws SAXException {
        if (enableAfter == null) {
          mEnableAfterTargetSdk = 0;
        } else {
          try {
            mEnableAfterTargetSdk = Integer.parseInt(enableAfter);
          } catch (NumberFormatException nfe) {
            throw new SAXException("Invalid SDK version int: " + enableAfter, nfe);
          }
        }
        return this;
      }
    }

  }

  private class CompatConfigXmlParser extends DefaultHandler {
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes)
        throws SAXException {
      if (qName.equals("compat-change")) {
        mCurrentChange = new CompatChange.Builder();
        String idStr = attributes.getValue("id");
        if (idStr == null) {
          throw new SAXException("<compat-change> element has no id");
        }
        try {
          mCurrentChange.id(Long.parseLong(idStr));
        } catch (NumberFormatException nfe) {
          throw new SAXException("<compat-change> id is not a valid long", nfe);
        }
        mCurrentChange.name(attributes.getValue("name"))
            .description(attributes.getValue("description"))
            .enableAfterTargetSdk(attributes.getValue("enableAfterTargetSdk"));

      } else if (qName.equals("meta-data")) {
        if (mCurrentChange == null) {
          throw new SAXException("<meta-data> tag with no enclosing <compat-change>");
        }
        mCurrentChange.definedInClass(attributes.getValue("definedIn"))
            .sourcePosition(attributes.getValue("sourcePosition"));
      }
    }

    @Override
    public void endElement(String uri, String localName, String qName) {
      if (qName.equals("compat-change")) {
        mChanges.add(mCurrentChange.build());
        mCurrentChange = null;
      }
    }
  }

  public static CompatInfo readCompatConfig(String source) {
    CompatInfo config = new CompatInfo();
    try {
      InputStream in = new FileInputStream(new File(source));

      XMLReader xmlreader = XMLReaderFactory.createXMLReader();
      xmlreader.setContentHandler(config.mXmlParser);
      xmlreader.setErrorHandler(config.mXmlParser);
      xmlreader.parse(new InputSource(in));
      in.close();
      return config;
    } catch (SAXException e) {
      throw new RuntimeException("Failed to parse " + source, e);
    } catch (IOException e) {
      throw new RuntimeException("Failed to read " + source, e);
    }
  }

  private final CompatConfigXmlParser mXmlParser = new CompatConfigXmlParser();
  private CompatChange.Builder mCurrentChange;
  private List<CompatChange> mChanges = new ArrayList<>();

  public List<CompatChange> getChanges() {
    return mChanges;
  }

  public void makeHDF(Data hdf) {
    // We construct a Comment for each compat change to re-use the default docs generation support
    // for comments.
    mChanges.sort(Comparator.comparing(a -> a.name));
    for (int i = 0; i < mChanges.size(); ++i) {
      CompatInfo.CompatChange change = mChanges.get(i);
      // we will get null ClassInfo here if the defining class is not in the SDK.
      ContainerInfo definedInContainer = Converter.obtainClass(change.definedInClass);
      if (definedInContainer == null) {
        // This happens when the class defining the @ChangeId constant is not included in
        // the sources that the SDK docs are generated from. Using package "android" as the
        // container works, but means we lose the context of the original javadoc comment.
        // This means that if the javadoc comment refers to classes imported by it's
        // containing source file, we cannot resolve those imports here.
        // TODO see if we could somehow plumb the import list from the original source file,
        // via compat_config.xml, so we can resolve links properly here?
        definedInContainer = Converter.obtainPackage("android");
      }
      if (change.description == null) {
        throw new RuntimeException("No desriprion found for @ChangeId " + change.name);
      }
      Comment comment = new Comment(change.description, definedInContainer, new SourcePositionInfo(
          change.sourceFile, change.sourceLine, 1));
      String path = "change." + i;
      hdf.setValue(path + ".id", Long.toString(change.id));
      hdf.setValue(path + ".name", change.name);
      if (change.enableAfterTargetSdk != 0) {
        hdf.setValue(path + ".enableAfterTargetSdk",
            Integer.toString(change.enableAfterTargetSdk));
      }
      TagInfo.makeHDF(hdf, path + ".descr", comment.tags());
    }
  }
}
