input: from typing import List
  
  def sentiment_analysis(review: List[str]) -> List[str]:
      """ Perform sentiment analysis on a list of product reviews using natural language processing techniques.
      The function will:
      1. Tokenize the reviews.
      2. Remove stopwords.
      3. Normalize the words.
      4. Generate features using CountVectorizer.
      5. Train a Naive Bayes classifier on the features.
      6. Predict the sentiment of the reviews.
      7. Return the predictions along with the classification report.
      
      >>> sentiment_analysis(['This product is amazing!', 'I hate this product.'])
      ['positive', 'negative']
      """
output:     
      from sklearn.feature_extraction.text import CountVectorizer
      from sklearn.naive_bayes import MultinomialNB
      from sklearn.pipeline import make_pipeline
      from sklearn.model_selection import train_test_split
      from sklearn.metrics import classification_report
      from nltk.corpus import stopwords
      from nltk.tokenize import word_tokenize
      from nltk.stem import WordNetLemmatizer
      import string
  
      # Sample data for training
      train_reviews = ['This product is amazing!', 'I hate this product.', 'Great product!', 'Terrible experience.']
      train_labels = ['positive', 'negative', 'positive', 'negative']
  
      # Tokenization
      def tokenize(text):
          tokens = word_tokenize(text)
          return [word.lower() for word in tokens if word.isalpha()]
  
      # Remove stopwords
      stop_words = set(stopwords.words('english'))
      def remove_stopwords(tokens):
          return [word for word in tokens if word not in stop_words]
  
      # Normalize words
      lemmatizer = WordNetLemmatizer()
      def normalize(tokens):
          return [lemmatizer.lemmatize(word) for word in tokens]
  
      # Preprocess the reviews
      def preprocess(reviews):
          processed_reviews = []
          for review in reviews:
              tokens = tokenize(review)
              tokens = remove_stopwords(tokens)
              tokens = normalize(tokens)
              processed_reviews.append(' '.join(tokens))
          return processed_reviews
  
      # Preprocess training data
      train_reviews = preprocess(train_reviews)
  
      # Create a pipeline with CountVectorizer and Naive Bayes classifier
      model = make_pipeline(CountVectorizer(), MultinomialNB())
  
      # Train the model
      model.fit(train_reviews, train_labels)
  
      # Preprocess the input reviews
      processed_reviews = preprocess(review)
  
      # Predict the sentiment
      predictions = model.predict(processed_reviews)
  
      # Return the predictions
      return predictions
  